Package com.eviware.soapui.impl.wsdl.submit.filters

Source Code of com.eviware.soapui.impl.wsdl.submit.filters.HttpRequestFilter

/*
* Copyright 2004-2014 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/

package com.eviware.soapui.impl.wsdl.submit.filters;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.rest.support.RestParamProperty;
import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder;
import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder.ParameterStyle;
import com.eviware.soapui.impl.rest.support.RestUtils;
import com.eviware.soapui.impl.support.HttpUtils;
import com.eviware.soapui.impl.support.http.HttpRequestInterface;
import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentDataSource;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.AttachmentUtils;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestDataSource;
import com.eviware.soapui.impl.wsdl.submit.transports.http.support.attachments.RestRequestMimeMessageRequestEntity;
import com.eviware.soapui.impl.wsdl.support.FileAttachment;
import com.eviware.soapui.impl.wsdl.support.PathUtils;
import com.eviware.soapui.impl.wsdl.teststeps.HttpTestRequest;
import com.eviware.soapui.model.iface.Attachment;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
import com.eviware.soapui.settings.HttpSettings;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.editor.inspectors.attachments.ContentTypeHandler;
import com.eviware.soapui.support.types.StringToStringMap;
import org.apache.commons.httpclient.URI;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.xmlbeans.XmlBoolean;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.PreencodedMimeBodyPart;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import static com.eviware.soapui.impl.support.HttpUtils.urlEncodeWithUtf8;

/**
* RequestFilter that adds SOAP specific headers
*
* @author Ole.Matzura
*/

public class HttpRequestFilter extends AbstractRequestFilter {
    @Override
    public void filterHttpRequest(SubmitContext context, HttpRequestInterface<?> request) {
        HttpRequestBase httpMethod = (HttpRequestBase) context.getProperty(BaseHttpRequestTransport.HTTP_METHOD);

        String path = PropertyExpander.expandProperties(context, request.getPath());
        StringBuilder query = new StringBuilder();
        String encoding = System.getProperty("soapui.request.encoding", StringUtils.unquote(request.getEncoding()));

        StringToStringMap responseProperties = (StringToStringMap) context
                .getProperty(BaseHttpRequestTransport.RESPONSE_PROPERTIES);

        MimeMultipart formMp = ("multipart/form-data".equals(request.getMediaType())
                || "multipart/mixed".equals(request.getMediaType()))
                && httpMethod instanceof HttpEntityEnclosingRequestBase ? new MimeMultipart() : null;

        RestParamsPropertyHolder params = request.getParams();

        for (int c = 0; c < params.getPropertyCount(); c++) {
            RestParamProperty param = params.getPropertyAt(c);

            String value = PropertyExpander.expandProperties(context, param.getValue());
            responseProperties.put(param.getName(), value);

            List<String> valueParts = sendEmptyParameters(request)
                    || (!StringUtils.hasContent(value) && param.getRequired()) ? RestUtils
                    .splitMultipleParametersEmptyIncluded(value, request.getMultiValueDelimiter()) : RestUtils
                    .splitMultipleParameters(value, request.getMultiValueDelimiter());

            // skip HEADER and TEMPLATE parameter encoding (TEMPLATE is encoded by
            // the URI handling further down)
            if (value != null && param.getStyle() != ParameterStyle.HEADER && param.getStyle() != ParameterStyle.TEMPLATE
                    && !param.isDisableUrlEncoding()) {
                try {
                    if (StringUtils.hasContent(encoding)) {
                        value = URLEncoder.encode(value, encoding);
                        for (int i = 0; i < valueParts.size(); i++) {
                            valueParts.set(i, URLEncoder.encode(valueParts.get(i), encoding));
                        }
                    } else {
                        value = urlEncodeWithUtf8(value);
                        for (int i = 0; i < valueParts.size(); i++) {
                            valueParts.set(i, urlEncodeWithUtf8(valueParts.get(i)));
                        }
                    }
                } catch (UnsupportedEncodingException e1) {
                    SoapUI.logError(e1);
                    value = urlEncodeWithUtf8(value);
                    for (int i = 0; i < valueParts.size(); i++) {
                        valueParts.set(i, urlEncodeWithUtf8(valueParts.get(i)));
                    }
                }
                // URLEncoder replaces space with "+", but we want "%20".
                value = value.replaceAll("\\+", "%20");
                for (int i = 0; i < valueParts.size(); i++) {
                    valueParts.set(i, valueParts.get(i).replaceAll("\\+", "%20"));
                }
            }

            if (param.getStyle() == ParameterStyle.QUERY && !sendEmptyParameters(request)) {
                if (!StringUtils.hasContent(value) && !param.getRequired()) {
                    continue;
                }
            }

            switch (param.getStyle()) {
                case HEADER:
                    for (String valuePart : valueParts) {
                        httpMethod.addHeader(param.getName(), valuePart);
                    }
                    break;
                case QUERY:
                    if (formMp == null || !request.isPostQueryString()) {
                        for (String valuePart : valueParts) {
                            if (query.length() > 0) {
                                query.append('&');
                            }

                            query.append(urlEncodeWithUtf8(param.getName()));
                            query.append('=');
                            if (StringUtils.hasContent(valuePart)) {
                                query.append(valuePart);
                            }
                        }
                    } else {
                        try {
                            addFormMultipart(request, formMp, param.getName(), responseProperties.get(param.getName()));
                        } catch (MessagingException e) {
                            SoapUI.logError(e);
                        }
                    }

                    break;
                case TEMPLATE:
                    try {
                        value = getEncodedValue(value, encoding, param.isDisableUrlEncoding(), request
                                .getSettings().getBoolean(HttpSettings.ENCODED_URLS));
                        path = path.replaceAll("\\{" + param.getName() + "\\}", value == null ? "" : value);
                    } catch (UnsupportedEncodingException e) {
                        SoapUI.logError(e);
                    }
                    break;
                case MATRIX:
                    try {
                        value = getEncodedValue(value, encoding, param.isDisableUrlEncoding(), request
                                .getSettings().getBoolean(HttpSettings.ENCODED_URLS));
                    } catch (UnsupportedEncodingException e) {
                        SoapUI.logError(e);
                    }

                    if (param.getType().equals(XmlBoolean.type.getName())) {
                        if (value.toUpperCase().equals("TRUE") || value.equals("1")) {
                            path += ";" + param.getName();
                        }
                    } else {
                        path += ";" + param.getName();
                        if (StringUtils.hasContent(value)) {
                            path += "=" + value;
                        }
                    }
                    break;
                case PLAIN:
                    break;
            }
        }

        if (request.getSettings().getBoolean(HttpSettings.FORWARD_SLASHES)) {
            path = PathUtils.fixForwardSlashesInPath(path);
        }

        if (PathUtils.isHttpPath(path)) {
            try {
                // URI(String) automatically URLencodes the input, so we need to
                // decode it first...
                URI uri = new URI(path, request.getSettings().getBoolean(HttpSettings.ENCODED_URLS));
                context.setProperty(BaseHttpRequestTransport.REQUEST_URI, uri);
                java.net.URI oldUri = httpMethod.getURI();
                httpMethod
                        .setURI(HttpUtils.createUri(oldUri.getScheme(), oldUri.getRawUserInfo(), oldUri.getHost(), oldUri.getPort(), oldUri.getRawPath(),
                                uri.getEscapedQuery(), oldUri.getRawFragment()));
            } catch (Exception e) {
                SoapUI.logError(e);
            }
        } else if (StringUtils.hasContent(path)) {
            try {
                java.net.URI oldUri = httpMethod.getURI();
                String pathToSet = StringUtils.hasContent(oldUri.getRawPath()) && !"/".equals(oldUri.getRawPath()) ? oldUri.getRawPath() + path : path;
                java.net.URI newUri = URIUtils.createURI(oldUri.getScheme(), oldUri.getHost(), oldUri.getPort(),
                        pathToSet, oldUri.getQuery(), oldUri.getFragment());
                httpMethod.setURI(newUri);
                context.setProperty(BaseHttpRequestTransport.REQUEST_URI, new URI(newUri.toString(), request
                        .getSettings().getBoolean(HttpSettings.ENCODED_URLS)));
            } catch (Exception e) {
                SoapUI.logError(e);
            }
        }

        if (query.length() > 0 && !request.isPostQueryString()) {
            try {
                java.net.URI oldUri = httpMethod.getURI();
                httpMethod.setURI(URIUtils.createURI(oldUri.getScheme(), oldUri.getHost(), oldUri.getPort(),
                        oldUri.getRawPath(), query.toString(), oldUri.getFragment()));
            } catch (Exception e) {
                SoapUI.logError(e);
            }
        }

        if (formMp != null) {
            // create request message
            try {
                if (request.hasRequestBody() && httpMethod instanceof HttpEntityEnclosingRequest) {
                    String requestContent = PropertyExpander.expandProperties(context, request.getRequestContent(),
                            request.isEntitizeProperties());
                    if (StringUtils.hasContent(requestContent)) {
                        initRootPart(request, requestContent, formMp);
                    }
                }

                for (Attachment attachment : request.getAttachments()) {
                    MimeBodyPart part = new PreencodedMimeBodyPart("binary");

                    if (attachment instanceof FileAttachment<?>) {
                        String name = attachment.getName();
                        if (StringUtils.hasContent(attachment.getContentID()) && !name.equals(attachment.getContentID())) {
                            name = attachment.getContentID();
                        }

                        part.setDisposition("form-data; name=\"" + name + "\"; filename=\"" + attachment.getName() + "\"");
                    } else {
                        part.setDisposition("form-data; name=\"" + attachment.getName() + "\"");
                    }

                    part.setDataHandler(new DataHandler(new AttachmentDataSource(attachment)));

                    formMp.addBodyPart(part);
                }

                MimeMessage message = new MimeMessage(AttachmentUtils.JAVAMAIL_SESSION);
                message.setContent(formMp);
                message.saveChanges();
                RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity(
                        message, request);
                ((HttpEntityEnclosingRequest) httpMethod).setEntity(mimeMessageRequestEntity);
                httpMethod.setHeader("Content-Type", mimeMessageRequestEntity.getContentType().getValue());
                httpMethod.setHeader("MIME-Version", "1.0");
            } catch (Throwable e) {
                SoapUI.logError(e);
            }
        } else if (request.hasRequestBody() && httpMethod instanceof HttpEntityEnclosingRequest) {
            if (StringUtils.hasContent(request.getMediaType())) {
                httpMethod.setHeader("Content-Type", getContentTypeHeader(request.getMediaType(), encoding));
            }

            if (request.isPostQueryString()) {
                try {
                    ((HttpEntityEnclosingRequest) httpMethod).setEntity(new StringEntity(query.toString()));
                } catch (UnsupportedEncodingException e) {
                    SoapUI.logError(e);
                }
            } else {
                String requestContent = PropertyExpander.expandProperties(context, request.getRequestContent(),
                        request.isEntitizeProperties());
                List<Attachment> attachments = new ArrayList<Attachment>();

                for (Attachment attachment : request.getAttachments()) {
                    if (attachment.getContentType().equals(request.getMediaType())) {
                        attachments.add(attachment);
                    }
                }

                if (StringUtils.hasContent(requestContent) && attachments.isEmpty()) {
                    try {
                        byte[] content = encoding == null ? requestContent.getBytes() : requestContent.getBytes(encoding);
                        ((HttpEntityEnclosingRequest) httpMethod).setEntity(new ByteArrayEntity(content));
                    } catch (UnsupportedEncodingException e) {
                        ((HttpEntityEnclosingRequest) httpMethod).setEntity(new ByteArrayEntity(requestContent
                                .getBytes()));
                    }
                } else if (attachments.size() > 0) {
                    try {
                        MimeMultipart mp = null;

                        if (StringUtils.hasContent(requestContent)) {
                            mp = new MimeMultipart();
                            initRootPart(request, requestContent, mp);
                        } else if (attachments.size() == 1) {
                            ((HttpEntityEnclosingRequest) httpMethod).setEntity(new InputStreamEntity(attachments.get(0)
                                    .getInputStream(), -1));

                            httpMethod.setHeader("Content-Type", getContentTypeHeader(request.getMediaType(), encoding));
                        }

                        if (((HttpEntityEnclosingRequest) httpMethod).getEntity() == null) {
                            if (mp == null) {
                                mp = new MimeMultipart();
                            }

                            // init mimeparts
                            AttachmentUtils.addMimeParts(request, attachments, mp, new StringToStringMap());

                            // create request message
                            MimeMessage message = new MimeMessage(AttachmentUtils.JAVAMAIL_SESSION);
                            message.setContent(mp);
                            message.saveChanges();
                            RestRequestMimeMessageRequestEntity mimeMessageRequestEntity = new RestRequestMimeMessageRequestEntity(
                                    message, request);
                            ((HttpEntityEnclosingRequest) httpMethod).setEntity(mimeMessageRequestEntity);
                            httpMethod.setHeader("Content-Type",
                                    getContentTypeHeader(mimeMessageRequestEntity.getContentType().getValue(), encoding));
                            httpMethod.setHeader("MIME-Version", "1.0");
                        }
                    } catch (Exception e) {
                        SoapUI.logError(e);
                    }
                }
            }
        }
    }

    private boolean sendEmptyParameters(HttpRequestInterface<?> request) {
        return request instanceof HttpTestRequest && ((HttpTestRequest) request).isSendEmptyParameters();
    }

    private String getContentTypeHeader(String contentType, String encoding) {
        return (encoding == null || encoding.trim().length() == 0) ? contentType : contentType + ";charset=" + encoding;
    }

    private void addFormMultipart(HttpRequestInterface<?> request, MimeMultipart formMp, String name, String value)
            throws MessagingException {
        MimeBodyPart part = new MimeBodyPart();

        if (value.startsWith("file:")) {
            String fileName = value.substring(5);
            File file = new File(fileName);
            part.setDisposition("form-data; name=\"" + name + "\"; filename=\"" + file.getName() + "\"");
            if (file.exists()) {
                part.setDataHandler(new DataHandler(new FileDataSource(file)));
            } else {
                for (Attachment attachment : request.getAttachments()) {
                    if (attachment.getName().equals(fileName)) {
                        part.setDataHandler(new DataHandler(new AttachmentDataSource(attachment)));
                        break;
                    }
                }
            }

            part.setHeader("Content-Type", ContentTypeHandler.getContentTypeFromFilename(file.getName()));
            part.setHeader("Content-Transfer-Encoding", "binary");
        } else {
            part.setDisposition("form-data; name=\"" + name + "\"");
            part.setText(value, System.getProperty("soapui.request.encoding", request.getEncoding()));
        }

        formMp.addBodyPart(part);
    }

    protected void initRootPart(HttpRequestInterface<?> wsdlRequest, String requestContent, MimeMultipart mp)
            throws MessagingException {
        MimeBodyPart rootPart = new PreencodedMimeBodyPart("8bit");
        // rootPart.setContentID( AttachmentUtils.ROOTPART_SOAPUI_ORG );
        mp.addBodyPart(rootPart, 0);

        DataHandler dataHandler = new DataHandler(new RestRequestDataSource(wsdlRequest, requestContent));
        rootPart.setDataHandler(dataHandler);
    }

    protected String getEncodedValue(String value, String encoding, boolean isDisableUrlEncoding, boolean isPreEncoded) throws UnsupportedEncodingException {

        if (value == null) {
            return "";
        }

        // get default encoding if there is no encoding set
        if (!StringUtils.hasContent(encoding)) {
            encoding = System.getProperty("file.encoding");
        }

        if (isAlreadyEncoded(value, encoding)) {
            // Already encoded so we don't do anything
            return value;
        } else if (isDisableUrlEncoding || isPreEncoded) {
            // If encoding is disabled or it is pre-encoded then we don't encode
            return value;
        } else {
            // encoding NOT disabled neither it is pre-encoded, so we encode here
            String encodedValue = URLEncoder.encode(value, encoding);
            // URLEncoder replaces space with "+", but we want "%20".
            return encodedValue.replaceAll("\\+", "%20");
        }

    }

    protected boolean isAlreadyEncoded(String path, String encoding) throws UnsupportedEncodingException {
        String decodedPath = java.net.URLDecoder.decode(path, encoding);
        return !path.equals(decodedPath);

    }

}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.submit.filters.HttpRequestFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.