Search in sources :

Example 1 with ProtocolTraceAction

use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.

the class HttpProtocol method recv_internal.

@Override
public CommMessage recv_internal(InputStream istream, OutputStream ostream) throws IOException {
    HttpMessage message = new HttpParser(istream).parse();
    String charset = HttpUtils.getCharset(null, message);
    CommMessage retVal = null;
    DecodedMessage decodedMessage = new DecodedMessage();
    HttpUtils.recv_checkForChannelClosing(message, channel());
    if (checkBooleanParameter(Parameters.DEBUG)) {
        boolean showContent = false;
        if (getParameterFirstValue(Parameters.DEBUG).getFirstChild("showContent").intValue() > 0 && message.size() > 0) {
            showContent = true;
        }
        Interpreter.getInstance().logInfo(getDebugMessage(message, charset, showContent));
    }
    // tracer
    Interpreter.getInstance().tracer().trace(() -> {
        try {
            final String traceMessage = getDebugMessage(message, charset, message.size() > 0);
            return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP MESSAGE RECEIVED", message.requestPath(), traceMessage, null);
        } catch (IOException e) {
            return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP MESSAGE RECEIVED", message.requestPath(), e.getMessage(), null);
        }
    });
    recv_checkForStatusCode(message);
    encoding = message.getProperty("accept-encoding");
    headRequest = inInputPort && message.isHead();
    String contentType = DEFAULT_CONTENT_TYPE;
    if (message.getProperty("content-type") != null) {
        contentType = message.getProperty("content-type").split(";", 2)[0].toLowerCase();
    }
    // URI parameter parsing
    if (message.requestPath() != null) {
        boolean strictEncoding = checkStringParameter(Parameters.JSON_ENCODING, "strict");
        recv_parseQueryString(message, decodedMessage.value, contentType, strictEncoding);
    }
    recv_parseRequestFormat(contentType);
    if (!message.isResponse()) {
        recv_checkReceivingOperation(message, decodedMessage);
    }
    /* https://tools.ietf.org/html/rfc7231#section-4.3 */
    if (!message.isGet() && !message.isHead()) {
        // body parsing
        if (message.size() > 0) {
            recv_parseMessage(message, decodedMessage, contentType, charset);
        }
    }
    if (!message.isResponse()) {
        recv_checkDefaultOp(message, decodedMessage);
    }
    if (checkBooleanParameter(Parameters.CONCURRENT)) {
        String messageId = message.getProperty(Headers.JOLIE_MESSAGE_ID);
        if (messageId != null) {
            try {
                decodedMessage.id = Long.parseLong(messageId);
            } catch (NumberFormatException e) {
            }
        }
    }
    if (message.isResponse()) {
        String responseHeader = "";
        if (hasParameter(Parameters.RESPONSE_HEADER) || hasOperationSpecificParameter(inputId, Parameters.RESPONSE_HEADER)) {
            if (hasOperationSpecificParameter(inputId, Parameters.RESPONSE_HEADER)) {
                responseHeader = getOperationSpecificStringParameter(inputId, Parameters.RESPONSE_HEADER);
            } else {
                responseHeader = getStringParameter(Parameters.RESPONSE_HEADER);
            }
            for (Entry<String, String> param : message.properties()) {
                decodedMessage.value.getFirstChild(responseHeader).getFirstChild(param.getKey()).setValue(param.getValue());
            }
            decodedMessage.value.getFirstChild(responseHeader).getFirstChild(Parameters.STATUS_CODE).setValue(message.statusCode());
        }
        recv_checkForSetCookie(message, decodedMessage.value);
        retVal = new CommMessage(decodedMessage.id, inputId, decodedMessage.resourcePath, decodedMessage.value, null);
    } else if (message.isError() == false) {
        recv_checkForMessageProperties(message, decodedMessage);
        retVal = new CommMessage(decodedMessage.id, decodedMessage.operationName, decodedMessage.resourcePath, decodedMessage.value, null);
    }
    if (retVal != null && "/".equals(retVal.resourcePath()) && channel().parentPort() != null && (channel().parentPort().getInterface().containsOperation(retVal.operationName()) || (channel().parentInputPort() != null && channel().parentInputPort().getAggregatedOperation(retVal.operationName()) != null))) {
        try {
            // The message is for this service
            boolean hasInput = false;
            OneWayTypeDescription oneWayTypeDescription = null;
            if (channel().parentInputPort() != null) {
                if (channel().parentInputPort().getAggregatedOperation(retVal.operationName()) != null) {
                    oneWayTypeDescription = channel().parentInputPort().getAggregatedOperation(retVal.operationName()).getOperationTypeDescription().asOneWayTypeDescription();
                    hasInput = true;
                }
            }
            if (!hasInput) {
                Interface iface = channel().parentPort().getInterface();
                oneWayTypeDescription = iface.oneWayOperations().get(retVal.operationName());
            }
            if (oneWayTypeDescription != null) {
                // We are receiving a One-Way message
                oneWayTypeDescription.requestType().cast(retVal.value());
            } else {
                hasInput = false;
                RequestResponseTypeDescription rrTypeDescription = null;
                if (channel().parentInputPort() != null) {
                    if (channel().parentInputPort().getAggregatedOperation(retVal.operationName()) != null) {
                        rrTypeDescription = channel().parentInputPort().getAggregatedOperation(retVal.operationName()).getOperationTypeDescription().asRequestResponseTypeDescription();
                        hasInput = true;
                    }
                }
                if (!hasInput) {
                    Interface iface = channel().parentPort().getInterface();
                    rrTypeDescription = iface.requestResponseOperations().get(retVal.operationName());
                }
                if (retVal.isFault()) {
                    Type faultType = rrTypeDescription.faults().get(retVal.fault().faultName());
                    if (faultType != null) {
                        faultType.cast(retVal.value());
                    }
                } else {
                    if (message.isResponse()) {
                        rrTypeDescription.responseType().cast(retVal.value());
                    } else {
                        rrTypeDescription.requestType().cast(retVal.value());
                    }
                }
            }
        } catch (TypeCastingException e) {
        // TODO: do something here?
        }
    }
    return retVal;
}
Also used : RequestResponseTypeDescription(jolie.runtime.typing.RequestResponseTypeDescription) ProtocolTraceAction(jolie.tracer.ProtocolTraceAction) IOException(java.io.IOException) OneWayTypeDescription(jolie.runtime.typing.OneWayTypeDescription) Type(jolie.runtime.typing.Type) NativeType(jolie.lang.NativeType) HttpParser(jolie.net.http.HttpParser) HttpMessage(jolie.net.http.HttpMessage) TypeCastingException(jolie.runtime.typing.TypeCastingException) Interface(jolie.net.ports.Interface)

Example 2 with ProtocolTraceAction

use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.

the class HttpProtocol method send_appendGenericHeaders.

private void send_appendGenericHeaders(CommMessage message, EncodedContent encodedContent, String charset, StringBuilder headerBuilder) throws IOException {
    if (!checkBooleanParameter(Parameters.KEEP_ALIVE, true)) {
        if (// we may do this only in input (server) mode
        inInputPort)
            channel().setToBeClosed(true);
        headerBuilder.append("Connection: close").append(HttpUtils.CRLF);
    }
    if (checkBooleanParameter(Parameters.CONCURRENT, true)) {
        headerBuilder.append(Headers.JOLIE_MESSAGE_ID).append(": ").append(message.id()).append(HttpUtils.CRLF);
    }
    headerBuilder.append(Headers.JOLIE_RESOURCE_PATH).append(": ").append(message.resourcePath()).append(HttpUtils.CRLF);
    String contentType = getStringParameter(Parameters.CONTENT_TYPE);
    if (contentType.length() > 0) {
        encodedContent.contentType = contentType;
    }
    encodedContent.contentType = encodedContent.contentType.toLowerCase();
    headerBuilder.append("Content-Type: ").append(encodedContent.contentType);
    if (charset != null) {
        headerBuilder.append("; charset=").append(charset.toLowerCase());
    }
    headerBuilder.append(HttpUtils.CRLF);
    if (encodedContent.content != null) {
        String transferEncoding = getStringParameter(Parameters.CONTENT_TRANSFER_ENCODING);
        if (transferEncoding.length() > 0) {
            headerBuilder.append("Content-Transfer-Encoding: ").append(transferEncoding).append(HttpUtils.CRLF);
        }
        String contentDisposition = getStringParameter(Parameters.CONTENT_DISPOSITION);
        if (contentDisposition.length() > 0) {
            encodedContent.contentDisposition = contentDisposition;
            headerBuilder.append("Content-Disposition: ").append(encodedContent.contentDisposition).append(HttpUtils.CRLF);
        }
        boolean compression = encoding != null && checkBooleanParameter(Parameters.COMPRESSION, true);
        String compressionTypes = getStringParameter(Parameters.COMPRESSION_TYPES, "text/html text/css text/plain text/xml text/x-js application/json application/javascript application/x-www-form-urlencoded application/xhtml+xml application/xml x-font/otf x-font/ttf application/x-font-ttf").toLowerCase();
        if (compression && !compressionTypes.equals("*") && !compressionTypes.contains(encodedContent.contentType)) {
            compression = false;
        }
        if (compression) {
            Interpreter.getInstance().tracer().trace(() -> {
                try {
                    final String traceMessage = encodedContent.content.toString(charset);
                    return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP COMPRESSING MESSAGE", message.resourcePath(), traceMessage, null);
                } catch (UnsupportedEncodingException e) {
                    return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP COMPRESSING MESSAGE", message.resourcePath(), e.getMessage(), null);
                }
            });
            encodedContent.content = HttpUtils.encode(encoding, encodedContent.content, headerBuilder);
        }
        headerBuilder.append("Content-Length: ").append(encodedContent.content.size()).append(HttpUtils.CRLF);
    } else {
        headerBuilder.append("Content-Length: 0").append(HttpUtils.CRLF);
    }
}
Also used : UnsupportedEncodingException(java.io.UnsupportedEncodingException) ProtocolTraceAction(jolie.tracer.ProtocolTraceAction)

Example 3 with ProtocolTraceAction

use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.

the class HttpProtocol method send_internal.

@Override
public void send_internal(OutputStream ostream, CommMessage message, InputStream istream) throws IOException {
    Method method = send_getRequestMethod(message);
    String charset = HttpUtils.getCharset(getStringParameter(Parameters.CHARSET, "utf-8"), null);
    String format = send_getFormat();
    String contentType = null;
    StringBuilder headerBuilder = new StringBuilder();
    if (inInputPort) {
        // We're responding to a request
        send_appendResponseHeaders(message, headerBuilder);
        send_appendResponseUserHeader(message, headerBuilder);
        send_appendHeader(headerBuilder);
    } else {
        // We're sending a notification or a solicit
        String qsFormat = "";
        if (method == Method.GET && getParameterFirstValue(Parameters.METHOD).hasChildren("queryFormat")) {
            if (getParameterFirstValue(Parameters.METHOD).getFirstChild("queryFormat").strValue().equals("json")) {
                qsFormat = format = "json";
                contentType = ContentTypes.APPLICATION_JSON;
            }
        }
        send_appendRequestUserHeader(message, headerBuilder);
        send_appendRequestHeaders(message, method, qsFormat, headerBuilder);
    }
    EncodedContent encodedContent = send_encodeContent(message, method, charset, format);
    if (contentType != null) {
        encodedContent.contentType = contentType;
    }
    send_appendGenericHeaders(message, encodedContent, charset, headerBuilder);
    headerBuilder.append(HttpUtils.CRLF);
    send_logDebugInfo(headerBuilder, encodedContent, charset);
    Interpreter.getInstance().tracer().trace(() -> {
        try {
            final String traceMessage = prepareSendDebugString(headerBuilder, encodedContent, charset, true);
            return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP MESSAGE SENT", message.resourcePath(), traceMessage, null);
        } catch (UnsupportedEncodingException e) {
            return new ProtocolTraceAction(ProtocolTraceAction.Type.HTTP, "HTTP MESSAGE SENT", message.resourcePath(), e.getMessage(), null);
        }
    });
    inputId = message.operationName();
    ostream.write(headerBuilder.toString().getBytes(HttpUtils.URL_DECODER_ENC));
    if (encodedContent.content != null && !headRequest) {
        ostream.write(encodedContent.content.getBytes());
    }
    headRequest = false;
}
Also used : UnsupportedEncodingException(java.io.UnsupportedEncodingException) ProtocolTraceAction(jolie.tracer.ProtocolTraceAction) Method(jolie.net.http.Method)

Example 4 with ProtocolTraceAction

use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.

the class SoapProtocol method recv_internal.

/*
	 * private Schema getRecvMessageValidationSchema() throws IOException { List< Source > sources = new
	 * ArrayList< Source >(); Definition definition = getWSDLDefinition(); if ( definition != null ) {
	 * Types types = definition.getTypes(); if ( types != null ) { List< ExtensibilityElement > list =
	 * types.getExtensibilityElements(); for( ExtensibilityElement element : list ) { if ( element
	 * instanceof SchemaImpl ) { sources.add( new DOMSource( ((SchemaImpl)element).getElement() ) ); } }
	 * } } SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI
	 * ); try { return schemaFactory.newSchema( sources.toArray( new Source[sources.size()] ) ); }
	 * catch( SAXException e ) { throw new IOException( e ); } }
	 */
public CommMessage recv_internal(InputStream istream, OutputStream ostream) throws IOException {
    HttpParser parser = new HttpParser(istream);
    HttpMessage message = parser.parse();
    String charset = HttpUtils.getCharset(null, message);
    HttpUtils.recv_checkForChannelClosing(message, channel());
    if (inInputPort && message.type() != HttpMessage.Type.POST) {
        throw new UnsupportedMethodException("Only HTTP method POST allowed!", Method.POST);
    }
    encoding = message.getProperty("accept-encoding");
    CommMessage retVal = null;
    String messageId = "";
    FaultException fault = null;
    Value value = Value.create();
    try {
        if (message.size() > 0) {
            if (checkBooleanParameter("debug")) {
                interpreter.logInfo("[SOAP debug] Receiving:\n" + new String(message.content(), charset));
            }
            SOAPMessage soapMessage = messageFactory.createMessage();
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            /*
				 * Schema messageSchema = getRecvMessageValidationSchema(); if ( messageSchema != null ) {
				 * factory.setIgnoringElementContentWhitespace( true ); factory.setSchema( messageSchema ); }
				 */
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            InputSource src = new InputSource(new ByteArrayInputStream(message.content()));
            src.setEncoding(charset);
            Document doc = builder.parse(src);
            DOMSource dom = new DOMSource(doc);
            soapMessage.getSOAPPart().setContent(dom);
            /*
				 * if ( checkBooleanParameter( "debugAfter" ) ) { ByteArrayOutputStream tmpStream = new
				 * ByteArrayOutputStream(); soapMessage.writeTo( tmpStream ); interpreter.logInfo(
				 * "[SOAP debug] Receiving:\n" + tmpStream.toString() ); }
				 */
            SOAPFault soapFault = soapMessage.getSOAPBody().getFault();
            if (soapFault == null) {
                Element soapValueElement = getFirstElement(soapMessage.getSOAPBody());
                messageId = soapValueElement.getLocalName();
                if (!channel().parentPort().getInterface().containsOperation(messageId)) {
                    String[] soapAction = message.getPropertyOrEmptyString("soapaction").replaceAll("\"", "").split("/");
                    messageId = soapAction[soapAction.length - 1];
                    if (checkBooleanParameter("debug")) {
                        interpreter.logInfo("Operation from SoapAction:" + messageId);
                    }
                }
                // explanation: https://github.com/jolie/jolie/issues/5
                xmlNodeToValue(value, soapValueElement, checkBooleanParameter("dropRootValue", false));
                ValueVector schemaPaths = getParameterVector("schema");
                if (schemaPaths.size() > 0) {
                    List<Source> sources = new LinkedList<>();
                    Value schemaPath;
                    for (int i = 0; i < schemaPaths.size(); i++) {
                        schemaPath = schemaPaths.get(i);
                        if (schemaPath.getChildren("validate").first().intValue() > 0) {
                            sources.add(new StreamSource(new File(schemaPaths.get(i).strValue())));
                        }
                    }
                    if (!sources.isEmpty()) {
                        Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(sources.toArray(new Source[0]));
                        schema.newValidator().validate(new DOMSource(soapMessage.getSOAPBody().getFirstChild()));
                    }
                }
            } else {
                String faultName = "UnknownFault";
                Value faultValue = Value.create();
                Detail d = soapFault.getDetail();
                if (d != null) {
                    Node n = d.getFirstChild();
                    if (n != null) {
                        faultName = n.getLocalName();
                        xmlNodeToValue(faultValue, n, true);
                    } else {
                        faultValue.setValue(soapFault.getFaultString());
                    }
                }
                fault = new FaultException(faultName, faultValue);
            }
        }
        String resourcePath = recv_getResourcePath(message);
        if (message.isResponse()) {
            if (fault != null && message.statusCode() == 500) {
                fault = new FaultException("InternalServerError", "");
            }
            retVal = new CommMessage(CommMessage.GENERIC_ID, inputId, resourcePath, value, fault);
        } else if (!message.isError()) {
            if (messageId.isEmpty()) {
                throw new IOException("Received SOAP Message without a specified operation");
            }
            retVal = new CommMessage(CommMessage.GENERIC_ID, messageId, resourcePath, value, fault);
        }
        final String mId = messageId;
        interpreter.tracer().trace(() -> {
            final StringBuilder traceMessage = new StringBuilder();
            try {
                traceMessage.append(getHeadersFromHttpMessage(message)).append("\n").append(new String(message.content(), charset));
                return new ProtocolTraceAction(ProtocolTraceAction.Type.SOAP, "SOAP MESSAGE RECEIVED", mId, traceMessage.toString(), null);
            } catch (UnsupportedEncodingException e) {
                return new ProtocolTraceAction(ProtocolTraceAction.Type.SOAP, "SOAP MESSAGE RECEIVED", mId, e.getMessage(), null);
            }
        });
    } catch (SOAPException | ParserConfigurationException e) {
        throw new IOException(e);
    } catch (SAXException e) {
        // TODO support resourcePath
        retVal = new CommMessage(CommMessage.GENERIC_ID, messageId, "/", value, new FaultException("TypeMismatch", e));
    }
    received = true;
    if (retVal != null && "/".equals(retVal.resourcePath()) && channel().parentPort() != null && channel().parentPort().getInterface().containsOperation(retVal.operationName())) {
        try {
            // The message is for this service
            Interface iface = channel().parentPort().getInterface();
            OneWayTypeDescription oneWayTypeDescription = iface.oneWayOperations().get(retVal.operationName());
            if (oneWayTypeDescription != null) {
                // We are receiving a One-Way message
                if (message.isResponse() == false) {
                    oneWayTypeDescription.requestType().cast(retVal.value());
                }
            } else {
                RequestResponseTypeDescription rrTypeDescription = iface.requestResponseOperations().get(retVal.operationName());
                if (retVal.isFault()) {
                    Type faultType = rrTypeDescription.faults().get(retVal.fault().faultName());
                    if (faultType != null) {
                        faultType.cast(retVal.value());
                    }
                } else if (message.isResponse()) {
                    rrTypeDescription.responseType().cast(retVal.value());
                } else {
                    rrTypeDescription.requestType().cast(retVal.value());
                }
            }
        } catch (TypeCastingException e) {
        // TODO: do something here?
        }
    }
    return retVal;
}
Also used : InputSource(org.xml.sax.InputSource) DOMSource(javax.xml.transform.dom.DOMSource) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) SOAPBodyElement(javax.xml.soap.SOAPBodyElement) SOAPElement(javax.xml.soap.SOAPElement) SOAPHeaderElement(javax.xml.soap.SOAPHeaderElement) ExtensibilityElement(javax.wsdl.extensions.ExtensibilityElement) Element(org.w3c.dom.Element) XSSchema(com.sun.xml.xsom.XSSchema) Schema(javax.xml.validation.Schema) Node(org.w3c.dom.Node) RequestResponseTypeDescription(jolie.runtime.typing.RequestResponseTypeDescription) ProtocolTraceAction(jolie.tracer.ProtocolTraceAction) Document(org.w3c.dom.Document) SOAPMessage(javax.xml.soap.SOAPMessage) DOMSource(javax.xml.transform.dom.DOMSource) StreamSource(javax.xml.transform.stream.StreamSource) Source(javax.xml.transform.Source) InputSource(org.xml.sax.InputSource) SAXException(org.xml.sax.SAXException) FaultException(jolie.runtime.FaultException) SOAPException(javax.xml.soap.SOAPException) HttpParser(jolie.net.http.HttpParser) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) UnsupportedMethodException(jolie.net.http.UnsupportedMethodException) StreamSource(javax.xml.transform.stream.StreamSource) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) OneWayTypeDescription(jolie.runtime.typing.OneWayTypeDescription) LinkedList(java.util.LinkedList) ValueVector(jolie.runtime.ValueVector) XSType(com.sun.xml.xsom.XSType) OperationType(javax.wsdl.OperationType) Type(jolie.runtime.typing.Type) XSComplexType(com.sun.xml.xsom.XSComplexType) XSContentType(com.sun.xml.xsom.XSContentType) DocumentBuilder(javax.xml.parsers.DocumentBuilder) ByteArrayInputStream(java.io.ByteArrayInputStream) Value(jolie.runtime.Value) SOAPFault(javax.xml.soap.SOAPFault) HttpMessage(jolie.net.http.HttpMessage) TypeCastingException(jolie.runtime.typing.TypeCastingException) File(java.io.File) Detail(javax.xml.soap.Detail) Interface(jolie.net.ports.Interface)

Example 5 with ProtocolTraceAction

use of jolie.tracer.ProtocolTraceAction in project jolie by jolie.

the class SoapProtocol method send_internal.

public void send_internal(OutputStream ostream, CommMessage message, InputStream istream) throws IOException {
    final StringBuilder httpMessage = new StringBuilder();
    ByteArray content = null;
    try {
        inputId = message.operationName();
        String messageNamespace = getOutputMessageNamespace(message.operationName());
        if (received) {
            // We're responding to a request
            inputId += "Response";
        }
        SOAPMessage soapMessage = messageFactory.createMessage();
        soapMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
        soapMessage.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8");
        SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
        setOutputEncodingStyle(soapEnvelope, message.operationName());
        SOAPBody soapBody = soapEnvelope.getBody();
        SOAPHeader soapHeader = soapEnvelope.getHeader();
        Value valueToSend = message.value();
        boolean basicAuthentication = false;
        String userpass = "";
        if (hasOperationSpecificParameter(message.operationName(), Parameters.HTTP_BASIC_AUTHENTICATION) || hasParameter(Parameters.HTTP_BASIC_AUTHENTICATION)) {
            Value basicAuthValue = null;
            if (hasOperationSpecificParameter(message.operationName(), Parameters.HTTP_BASIC_AUTHENTICATION)) {
                basicAuthValue = getOperationSpecificParameterFirstValue(message.operationName(), Parameters.HTTP_BASIC_AUTHENTICATION);
            } else {
                basicAuthValue = getParameterFirstValue(Parameters.HTTP_BASIC_AUTHENTICATION);
            }
            userpass = basicAuthValue.getFirstChild("userid").strValue() + ":" + basicAuthValue.getFirstChild("password").strValue();
            Base64.Encoder encoder = Base64.getEncoder();
            userpass = encoder.encodeToString(userpass.getBytes());
            basicAuthentication = true;
        }
        if (checkBooleanParameter("wsAddressing")) {
            // WS-Addressing namespace
            soapHeader.addNamespaceDeclaration("wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
            // Message ID
            Name messageIdName = soapEnvelope.createName("MessageID", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
            SOAPHeaderElement messageIdElement = soapHeader.addHeaderElement(messageIdName);
            if (received) {
                // TODO: remove this after we implement a mechanism for being sure message.id() is the one received
                // before.
                messageIdElement.setValue("uuid:1");
            } else {
                messageIdElement.setValue("uuid:" + message.id());
            }
            // Action element
            Name actionName = soapEnvelope.createName("Action", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
            SOAPHeaderElement actionElement = soapHeader.addHeaderElement(actionName);
            /*
				 * TODO: the action element could be specified within the parameter. Perhaps wsAddressing.action ?
				 * We could also allow for giving a prefix or a suffix to the operation name, like
				 * wsAddressing.action.prefix, wsAddressing.action.suffix
				 */
            actionElement.setValue(message.operationName());
            // From element
            Name fromName = soapEnvelope.createName("From", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
            SOAPHeaderElement fromElement = soapHeader.addHeaderElement(fromName);
            Name addressName = soapEnvelope.createName("Address", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
            SOAPElement addressElement = fromElement.addChildElement(addressName);
            addressElement.setValue("http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous");
        // To element
        /*
				 * if ( operation == null ) { // we are sending a Notification or a Solicit Name toName =
				 * soapEnvelope.createName("To", "wsa", "http://schemas.xmlsoap.org/ws/2004/03/addressing");
				 * SOAPHeaderElement toElement=soapHeader.addHeaderElement(toName);
				 * toElement.setValue(getURI().getHost()); }
				 */
        }
        if (message.isFault()) {
            FaultException f = message.fault();
            SOAPFault soapFault = soapBody.addFault();
            soapFault.setFaultCode(soapEnvelope.createQName("Server", soapEnvelope.getPrefix()));
            soapFault.setFaultString(f.getMessage());
            Detail detail = soapFault.addDetail();
            DetailEntry de = detail.addDetailEntry(soapEnvelope.createName(f.faultName(), null, messageNamespace));
            valueToSOAPElement(f.value(), de, soapEnvelope);
        } else {
            XSSchemaSet sSet = getSchemaSet();
            XSElementDecl elementDecl;
            String messageRootElementName = getOutputMessageRootElementName(message.operationName());
            if (sSet == null || (elementDecl = sSet.getElementDecl(messageNamespace, messageRootElementName)) == null) {
                Name operationName;
                soapEnvelope.addNamespaceDeclaration("xsi", XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
                soapEnvelope.addNamespaceDeclaration("xsd", XMLConstants.W3C_XML_SCHEMA_NS_URI);
                if (messageNamespace.isEmpty()) {
                    operationName = soapEnvelope.createName(messageRootElementName);
                } else {
                    soapEnvelope.addNamespaceDeclaration("jolieMessage", messageNamespace);
                    operationName = soapEnvelope.createName(messageRootElementName, "jolieMessage", messageNamespace);
                }
                /*
					 * if( hasParameter( "header") ) { if ( getParameterFirstValue( "header" ).hasChildren() ) { //
					 * Prepare SOAP Header getting data from parameter .header SOAPHeader soapHeader =
					 * soapEnvelope.getHeader();
					 * 
					 * } }
					 */
                SOAPBodyElement opBody = soapBody.addBodyElement(operationName);
                String[] parameters = getParameterOrder(message.operationName());
                if (parameters == null) {
                    valueToSOAPElement(valueToSend, opBody, soapEnvelope);
                } else {
                    for (String parameterName : parameters) {
                        valueToSOAPElement(valueToSend.getFirstChild(parameterName), opBody.addChildElement(parameterName), soapEnvelope);
                    }
                }
            } else {
                initNamespacePrefixes(soapEnvelope);
                if (hasParameter(Parameters.ADD_ATTRIBUTE)) {
                    Value add_parameter = getParameterFirstValue(Parameters.ADD_ATTRIBUTE);
                    if (add_parameter.hasChildren(Parameters.ENVELOPE)) {
                        // attributes must be added to the envelope
                        ValueVector attributes = add_parameter.getFirstChild(Parameters.ENVELOPE).getChildren("attribute");
                        for (Value att : attributes) {
                            soapEnvelope.addNamespaceDeclaration(att.getFirstChild("name").strValue(), att.getFirstChild("value").strValue());
                        }
                    }
                }
                boolean wrapped = true;
                Value vStyle = getParameterVector(Parameters.STYLE).first();
                if ("document".equals(vStyle.strValue())) {
                    wrapped = vStyle.getFirstChild(Parameters.WRAPPED).boolValue();
                }
                SOAPElement opBody = soapBody;
                if (wrapped) {
                    List<ExtensibilityElement> listExt;
                    if (received) {
                        listExt = getWSDLPort().getBinding().getBindingOperation(message.operationName(), null, null).getBindingOutput().getExtensibilityElements();
                    } else {
                        listExt = getWSDLPort().getBinding().getBindingOperation(message.operationName(), null, null).getBindingInput().getExtensibilityElements();
                    }
                    for (ExtensibilityElement extElement : listExt) {
                        if (extElement instanceof SOAPHeaderImpl) {
                            SOAPHeaderImpl soapHeaderImpl = (SOAPHeaderImpl) extElement;
                            if (valueToSend.getChildren(soapHeaderImpl.getPart()).size() > 0) {
                                Definition definition = getWSDLDefinition();
                                Message wsdlMessage = definition.getMessage(soapHeaderImpl.getMessage());
                                XSElementDecl partElementDeclaration = sSet.getElementDecl(wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getNamespaceURI(), wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getLocalPart());
                                SOAPHeaderElement headerElement = soapHeader.addHeaderElement(soapEnvelope.createName(wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getLocalPart(), wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getPrefix(), wsdlMessage.getPart(soapHeaderImpl.getPart()).getElementName().getNamespaceURI()));
                                valueToTypedSOAP(valueToSend.getFirstChild(soapHeaderImpl.getPart()), partElementDeclaration, headerElement, soapEnvelope, !wrapped, sSet, partElementDeclaration.getTargetNamespace());
                                valueToSend.children().remove(soapHeaderImpl.getPart());
                            }
                        }
                    }
                    opBody = soapBody.addBodyElement(soapEnvelope.createName(messageRootElementName, namespacePrefixMap.get(elementDecl.getOwnerSchema().getTargetNamespace()), null));
                    // adding forced attributes to operation
                    if (hasParameter(Parameters.ADD_ATTRIBUTE)) {
                        Value add_parameter = getParameterFirstValue(Parameters.ADD_ATTRIBUTE);
                        if (add_parameter.hasChildren(Parameters.OPERATION)) {
                            ValueVector operations = add_parameter.getChildren(Parameters.OPERATION);
                            for (Value op : operations) {
                                if (op.getFirstChild("operation_name").strValue().equals(message.operationName())) {
                                    // attributes must be added to the envelope
                                    Value attribute = op.getFirstChild("attribute");
                                    QName attrName;
                                    if (attribute.hasChildren("prefix")) {
                                        attrName = opBody.createQName(attribute.getFirstChild("name").strValue(), attribute.getFirstChild("prefix").strValue());
                                    } else {
                                        attrName = opBody.createQName(attribute.getFirstChild("name").strValue(), null);
                                    }
                                    opBody.addAttribute(attrName, attribute.getFirstChild("value").strValue());
                                }
                            }
                        }
                    }
                }
                // check if the body has been defined with more than one parts
                // Operation operation =
                // getWSDLPort().getBinding().getPortType().getOperation( message.operationName(), null, null );
                // Message wsdlMessage;
                List<ExtensibilityElement> listExt;
                if (received) {
                    // We are sending a response
                    // wsdlMessage = operation.getOutput().getMessage();
                    listExt = getWSDLPort().getBinding().getBindingOperation(message.operationName(), null, null).getBindingOutput().getExtensibilityElements();
                } else {
                    // We are sending a request
                    // wsdlMessage = operation.getInput().getMessage();
                    listExt = getWSDLPort().getBinding().getBindingOperation(message.operationName(), null, null).getBindingInput().getExtensibilityElements();
                }
                boolean partsInBody = false;
                String partName = "";
                for (ExtensibilityElement element : listExt) {
                    if (element instanceof SOAPBodyImpl) {
                        SOAPBodyImpl sBodyImpl = (SOAPBodyImpl) element;
                        if (sBodyImpl.getParts() != null && sBodyImpl.getParts().size() > 0) {
                            partName = sBodyImpl.getParts().get(0).toString();
                            partsInBody = true;
                        }
                    }
                }
                if (!partsInBody) {
                    valueToTypedSOAP(valueToSend, elementDecl, opBody, soapEnvelope, !wrapped, sSet, messageNamespace);
                } else {
                    // we support only body with one element as a root
                    valueToTypedSOAP(valueToSend.getFirstChild(partName), elementDecl, opBody, soapEnvelope, !wrapped, sSet, messageNamespace);
                }
            }
        }
        if (soapEnvelope.getHeader().hasChildNodes() == false) {
            // Some service implementations do not like empty headers
            soapEnvelope.getHeader().detachNode();
        }
        ByteArrayOutputStream tmpStream = new ByteArrayOutputStream();
        soapMessage.writeTo(tmpStream);
        content = new ByteArray(tmpStream.toByteArray());
        String soapAction = null;
        if (received) {
            // We're responding to a request
            if (message.isFault()) {
                httpMessage.append("HTTP/1.1 500 Internal Server Error").append(HttpUtils.CRLF);
            } else {
                httpMessage.append("HTTP/1.1 200 OK").append(HttpUtils.CRLF);
            }
            httpMessage.append("Server: Jolie").append(HttpUtils.CRLF);
            received = false;
        } else {
            // We're sending a notification or a solicit
            // TODO: fix this to consider resourcePaths
            String path = uri.getRawPath();
            if (path == null || path.length() == 0) {
                path = "*";
            }
            httpMessage.append("POST ").append(path).append(" HTTP/1.1").append(HttpUtils.CRLF).append("Host: ").append(uri.getHost()).append(HttpUtils.CRLF);
            /* basic authentication: code replication from HttpProtocol. Refactoring is needed */
            if (basicAuthentication) {
                httpMessage.append("Authorization: Basic ").append(userpass).append(HttpUtils.CRLF);
            }
            /*
				 * soapAction = "SOAPAction: \"" + messageNamespace + "/" + message.operationName() + '\"' +
				 * HttpUtils.CRLF;
				 */
            soapAction = "SOAPAction: \"" + getSoapActionForOperation(message.operationName()) + '\"' + HttpUtils.CRLF;
            if (checkBooleanParameter("compression", true)) {
                String requestCompression = getStringParameter("requestCompression");
                if (requestCompression.equals("gzip") || requestCompression.equals("deflate")) {
                    encoding = requestCompression;
                    httpMessage.append("Accept-Encoding: ").append(encoding).append(HttpUtils.CRLF);
                } else {
                    httpMessage.append("Accept-Encoding: gzip, deflate").append(HttpUtils.CRLF);
                }
            }
        }
        if (getParameterVector("keepAlive").first().intValue() != 1) {
            if (received)
                // we may do this only in input (server) mode
                channel().setToBeClosed(true);
            httpMessage.append("Connection: close").append(HttpUtils.CRLF);
        }
        ByteArray plainTextContent = content;
        if (encoding != null && checkBooleanParameter("compression", true)) {
            content = HttpUtils.encode(encoding, content, httpMessage);
        }
        // httpMessage.append("Content-Type: application/soap+xml; charset=utf-8" + HttpUtils.CRLF);
        httpMessage.append("Content-Type: text/xml; charset=utf-8").append(HttpUtils.CRLF);
        httpMessage.append("Content-Length: ").append(content.size()).append(HttpUtils.CRLF);
        if (soapAction != null) {
            httpMessage.append(soapAction);
        }
        httpMessage.append(HttpUtils.CRLF);
        if (getParameterVector("debug").first().intValue() > 0) {
            interpreter.logInfo("[SOAP debug] Sending:\n" + httpMessage.toString() + plainTextContent.toString("utf-8"));
        }
        interpreter.tracer().trace(() -> {
            try {
                final String traceMessage = httpMessage.toString() + plainTextContent.toString("utf-8");
                return new ProtocolTraceAction(ProtocolTraceAction.Type.SOAP, "SOAP MESSAGE SENT", message.operationName(), traceMessage, null);
            } catch (UnsupportedEncodingException e) {
                return new ProtocolTraceAction(ProtocolTraceAction.Type.SOAP, "SOAP MESSAGE SENT", message.operationName(), e.getMessage(), null);
            }
        });
        inputId = message.operationName();
    } catch (Exception e) {
        if (received) {
            httpMessage.setLength(0);
            try {
                SOAPMessage soapMessage = messageFactory.createMessage();
                soapMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
                soapMessage.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8");
                SOAPEnvelope soapEnvelope = soapMessage.getSOAPPart().getEnvelope();
                setOutputEncodingStyle(soapEnvelope, message.operationName());
                SOAPBody soapBody = soapEnvelope.getBody();
                SOAPFault soapFault = soapBody.addFault();
                soapFault.setFaultCode(soapEnvelope.createQName("Server", soapEnvelope.getPrefix()));
                soapFault.setFaultString("Error found in SOAP/XML format");
                ByteArrayOutputStream tmpStream = new ByteArrayOutputStream();
                soapMessage.writeTo(tmpStream);
                content = new ByteArray(tmpStream.toByteArray());
                httpMessage.append("HTTP/1.1 500 Internal Server Error").append(HttpUtils.CRLF).append("Server: Jolie").append(HttpUtils.CRLF).append("Connection: close").append(HttpUtils.CRLF).append("Content-Type: text/xml; charset=utf-8").append(HttpUtils.CRLF).append("Content-Length: ").append(content.size()).append(HttpUtils.CRLF).append(HttpUtils.CRLF);
            } catch (SOAPException se) {
                System.out.println(se.getMessage());
            }
        } else {
            throw new IOException(e);
        }
    }
    ostream.write(httpMessage.toString().getBytes(HttpUtils.URL_DECODER_ENC));
    if (content != null) {
        ostream.write(content.getBytes());
    }
}
Also used : Base64(java.util.Base64) SOAPMessage(javax.xml.soap.SOAPMessage) Message(javax.wsdl.Message) HttpMessage(jolie.net.http.HttpMessage) DetailEntry(javax.xml.soap.DetailEntry) XSSchemaSet(com.sun.xml.xsom.XSSchemaSet) ProtocolTraceAction(jolie.tracer.ProtocolTraceAction) SOAPEnvelope(javax.xml.soap.SOAPEnvelope) SOAPBodyImpl(com.ibm.wsdl.extensions.soap.SOAPBodyImpl) SOAPMessage(javax.xml.soap.SOAPMessage) ExtensibilityElement(javax.wsdl.extensions.ExtensibilityElement) QName(javax.xml.namespace.QName) Name(javax.xml.soap.Name) FaultException(jolie.runtime.FaultException) SOAPException(javax.xml.soap.SOAPException) SOAPElement(javax.xml.soap.SOAPElement) ByteArray(jolie.runtime.ByteArray) SOAPHeader(javax.xml.soap.SOAPHeader) SOAPBodyElement(javax.xml.soap.SOAPBodyElement) SOAPHeaderElement(javax.xml.soap.SOAPHeaderElement) QName(javax.xml.namespace.QName) Definition(javax.wsdl.Definition) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) SOAPHeaderImpl(com.ibm.wsdl.extensions.soap.SOAPHeaderImpl) SOAPException(javax.xml.soap.SOAPException) TransformerException(javax.xml.transform.TransformerException) FaultException(jolie.runtime.FaultException) IOException(java.io.IOException) TypeCastingException(jolie.runtime.typing.TypeCastingException) SAXException(org.xml.sax.SAXException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) UnsupportedMethodException(jolie.net.http.UnsupportedMethodException) WSDLException(javax.wsdl.WSDLException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) ValueVector(jolie.runtime.ValueVector) SOAPBody(javax.xml.soap.SOAPBody) Value(jolie.runtime.Value) SOAPFault(javax.xml.soap.SOAPFault) XSElementDecl(com.sun.xml.xsom.XSElementDecl) Detail(javax.xml.soap.Detail)

Aggregations

ProtocolTraceAction (jolie.tracer.ProtocolTraceAction)5 UnsupportedEncodingException (java.io.UnsupportedEncodingException)4 IOException (java.io.IOException)3 HttpMessage (jolie.net.http.HttpMessage)3 TypeCastingException (jolie.runtime.typing.TypeCastingException)3 ExtensibilityElement (javax.wsdl.extensions.ExtensibilityElement)2 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)2 Detail (javax.xml.soap.Detail)2 SOAPBodyElement (javax.xml.soap.SOAPBodyElement)2 SOAPElement (javax.xml.soap.SOAPElement)2 SOAPException (javax.xml.soap.SOAPException)2 SOAPFault (javax.xml.soap.SOAPFault)2 SOAPHeaderElement (javax.xml.soap.SOAPHeaderElement)2 SOAPMessage (javax.xml.soap.SOAPMessage)2 HttpParser (jolie.net.http.HttpParser)2 UnsupportedMethodException (jolie.net.http.UnsupportedMethodException)2 Interface (jolie.net.ports.Interface)2 FaultException (jolie.runtime.FaultException)2 Value (jolie.runtime.Value)2 ValueVector (jolie.runtime.ValueVector)2