/**
* Copyright 2007-2015, Kaazing Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kaazing.k3po.lang.internal.parser;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.READ_CHUNK_TRAILER;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.READ_CLOSED;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.READ_HTTP_HEADER;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.READ_HTTP_METHOD;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.READ_HTTP_PARAMETER;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.READ_HTTP_STATUS;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.READ_HTTP_VERSION;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.SCRIPT;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_CLOSE;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_FLUSH;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_HTTP_CONTENT_LENGTH;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_HTTP_HEADER;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_HTTP_HOST;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_HTTP_METHOD;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_HTTP_PARAMETER;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_HTTP_REQUEST;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_HTTP_STATUS;
import static org.kaazing.k3po.lang.internal.parser.ScriptParseStrategy.WRITE_HTTP_VERSION;
import static org.kaazing.k3po.lang.internal.test.junit.Assert.assertEquals;
import java.net.URI;
import org.junit.Test;
import org.kaazing.k3po.lang.internal.ast.AstReadClosedNode;
import org.kaazing.k3po.lang.internal.ast.AstReadConfigNode;
import org.kaazing.k3po.lang.internal.ast.AstReadOptionNode;
import org.kaazing.k3po.lang.internal.ast.AstScriptNode;
import org.kaazing.k3po.lang.internal.ast.AstWriteCloseNode;
import org.kaazing.k3po.lang.internal.ast.AstWriteConfigNode;
import org.kaazing.k3po.lang.internal.ast.AstWriteFlushNode;
import org.kaazing.k3po.lang.internal.ast.AstWriteOptionNode;
import org.kaazing.k3po.lang.internal.ast.builder.AstReadClosedNodeBuilder;
import org.kaazing.k3po.lang.internal.ast.builder.AstReadConfigNodeBuilder;
import org.kaazing.k3po.lang.internal.ast.builder.AstReadOptionNodeBuilder;
import org.kaazing.k3po.lang.internal.ast.builder.AstScriptNodeBuilder;
import org.kaazing.k3po.lang.internal.ast.builder.AstWriteCloseNodeBuilder;
import org.kaazing.k3po.lang.internal.ast.builder.AstWriteConfigNodeBuilder;
import org.kaazing.k3po.lang.internal.ast.builder.AstWriteFlushNodeBuilder;
import org.kaazing.k3po.lang.internal.ast.builder.AstWriteOptionNodeBuilder;
import org.kaazing.k3po.lang.internal.ast.value.AstLocation;
import org.kaazing.k3po.lang.internal.ast.value.AstLocationLiteral;
import org.kaazing.k3po.lang.internal.el.ExpressionContext;
public class HttpScriptParserTest {
@Test
public void shouldParseWriteHttpRequestOriginForm() throws Exception {
String scriptFragment = "write request \"origin-form\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_REQUEST);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("request")
.setValue("form", "origin-form")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(1, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteHttpRequestAbsoluteForm() throws Exception {
String scriptFragment = "write request \"absolute-form\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_REQUEST);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("request")
.setValue("form", "absolute-form")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(1, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadHttpHeaderMissing() throws Exception {
String scriptFragment = "read header \"Connection\" missing";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadConfigNode actual = parser.parseWithStrategy(scriptFragment, READ_HTTP_HEADER);
// @formatter:off
AstReadConfigNode expected = new AstReadConfigNodeBuilder()
.setType("header missing")
.setValueExactText("name", "Connection")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(1, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadHttpHeaderExactText() throws Exception {
String scriptFragment = "read header \"Host\" \"localhost:8000\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadConfigNode actual = parser.parseWithStrategy(scriptFragment, READ_HTTP_HEADER);
// @formatter:off
AstReadConfigNode expected = new AstReadConfigNodeBuilder()
.setType("header")
.setValueExactText("name", "Host")
.addMatcherExactText("localhost:8000")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(2, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteHttpHeaderExactText() throws Exception {
String scriptFragment = "write header \"Host\" \"localhost:8000\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_HEADER);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("header")
.setName("name", "Host")
.addValue("localhost:8000")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(2, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteHttpContentLength() throws Exception {
String scriptFragment = "write header content-length";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_CONTENT_LENGTH);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("content-length")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(0, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteHttpHost() throws Exception {
String scriptFragment = "write header host";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_HOST);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("host")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(0, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadHttpMethodExactTest() throws Exception {
String scriptFragment = "read method \"get\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadConfigNode actual = parser.parseWithStrategy(scriptFragment, READ_HTTP_METHOD);
// @formatter:off
AstReadConfigNode expected = new AstReadConfigNodeBuilder()
.setType("method")
.setMatcherExactText("name", "get")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(1, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteHttpMethodExactTest() throws Exception {
String scriptFragment = "write method \"get\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_METHOD);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("method")
.addValue("get")
.done();
// @formatter:on
assertEquals(expected, actual);
// Zero list region info because of WriteConfigNode parsing but perhaps we
// should change that
assertEquals(0, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadHttpParameterExactTest() throws Exception {
String scriptFragment = "read parameter \".kl\" \"y\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadConfigNode actual = parser.parseWithStrategy(scriptFragment, READ_HTTP_PARAMETER);
// @formatter:off
AstReadConfigNode expected = new AstReadConfigNodeBuilder()
.setType("parameter")
.setValueExactText("name", ".kl")
.addMatcherExactText("y")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(2, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteHttpParameterExactTest() throws Exception {
String scriptFragment = "write parameter \".kl\" \"y\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_PARAMETER);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("parameter")
.setName("name", ".kl")
.addValue("y")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(2, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadHttpVersionExactTest() throws Exception {
String scriptFragment = "read version \"Http/1.1\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadConfigNode actual = parser.parseWithStrategy(scriptFragment, READ_HTTP_VERSION);
// @formatter:off
AstReadConfigNode expected = new AstReadConfigNodeBuilder()
.setType("version")
.setMatcherExactText("version", "Http/1.1")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(1, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteHttpVersionExactTest() throws Exception {
String scriptFragment = "write version \"Http/1.1\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_VERSION);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("version")
.addValue("Http/1.1")
.done();
// @formatter:on
assertEquals(expected, actual);
// Zero list region info because of WriteConfigNode parsing but perhaps we
// should change that
assertEquals(0, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadHttpStatusExactTest() throws Exception {
String scriptFragment = "read status \"403\" \"Unauthorized\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadConfigNode actual = parser.parseWithStrategy(scriptFragment, READ_HTTP_STATUS);
// @formatter:off
AstReadConfigNode expected = new AstReadConfigNodeBuilder()
.setType("status")
.setMatcherExactText("code", "403")
.setMatcherExactText("reason", "Unauthorized")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(2, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteHttpStatusExactTest() throws Exception {
String scriptFragment = "write status \"403\" \"Unauthorized\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, WRITE_HTTP_STATUS);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("status")
.setValue("code", "403")
.setValue("reason", "Unauthorized")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(2, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadClose() throws Exception {
String scriptFragment = "read closed";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadClosedNode actual = parser.parseWithStrategy(scriptFragment, READ_CLOSED);
// @formatter:off
AstReadClosedNode expected = new AstReadClosedNodeBuilder()
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(0, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteFlush() throws Exception {
String scriptFragment = "write flush";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteFlushNode actual = parser.parseWithStrategy(scriptFragment, WRITE_FLUSH);
// @formatter:off
AstWriteFlushNode expected = new AstWriteFlushNodeBuilder()
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(0, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteClose() throws Exception {
String scriptFragment = "write close";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteCloseNode actual = parser.parseWithStrategy(scriptFragment, WRITE_CLOSE);
// @formatter:off
AstWriteCloseNode expected = new AstWriteCloseNodeBuilder()
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(0, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteOptionChunkExtension() throws Exception {
String scriptFragment = "write option chunkExtension \"chunkextension\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteOptionNode actual = parser.parseWithStrategy(scriptFragment, ScriptParseStrategy.WRITE_CHUNK_EXTENSION_OPTION);
// @formatter:off
AstWriteOptionNode expected = new AstWriteOptionNodeBuilder()
.setOptionName("chunkExtension")
.setOptionValue("chunkextension")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(1, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadOptionChunkExtension() throws Exception {
String scriptFragment = "read option chunkExtension \"chunkextension\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadOptionNode actual = parser.parseWithStrategy(scriptFragment, ScriptParseStrategy.READ_CHUNK_EXTENSION_OPTION);
// @formatter:off
AstReadOptionNode expected = new AstReadOptionNodeBuilder()
// .
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(1, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseWriteChunkTrailer() throws Exception {
String scriptFragment = "write trailer \"checksum\" \"value\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstWriteConfigNode actual = parser.parseWithStrategy(scriptFragment, ScriptParseStrategy.WRITE_CHUNK_TRAILER);
// @formatter:off
AstWriteConfigNode expected = new AstWriteConfigNodeBuilder()
.setType("trailer")
.setName("name", "checksum")
.addValue("value")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(2, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseReadChunkTrailer() throws Exception {
String scriptFragment = "read trailer \"checksum\" \"value\"";
ScriptParserImpl parser = new ScriptParserImpl();
AstReadConfigNode actual = parser.parseWithStrategy(scriptFragment, READ_CHUNK_TRAILER);
// @formatter:off
AstReadConfigNode expected = new AstReadConfigNodeBuilder()
.setType("trailer")
.setValueExactText("name", "checksum")
.addMatcherExactText("value")
.done();
// @formatter:on
assertEquals(expected, actual);
assertEquals(2, actual.getRegionInfo().children.size());
}
@Test
public void shouldParseHttpReadRequestWriteResponseScript() throws Exception {
// @formatter:off
String script =
"accept http://somehost:8000/path\n" +
"accepted\n" +
"read method \"get\"\n" +
"read parameter \".kl\" \"y\"\n" +
"read header \"Upgrade\" \"websocket\"\n" +
"read [0x82]\n" +
"read closed\n" +
"write status \"101\" \"Switching Protocols\"\n" +
"write header \"upgrade\" \"websocket\"\n" +
"write close \n" +
"close\n" +
"closed\n";
// @formatter:on
ScriptParserImpl parser = new ScriptParserImpl();
AstScriptNode actual = parser.parseWithStrategy(script, SCRIPT);
// @formatter:off
AstScriptNode expected = new AstScriptNodeBuilder()
.addAcceptStream()
.setLocation(new AstLocationLiteral(URI.create("http://somehost:8000/path")))
.done()
.addAcceptedStream()
.addReadConfigEvent()
.setType("method")
.setMatcherExactText("name", "get")
.done()
.addReadConfigEvent()
.setType("parameter")
.setValueExactText("name", ".kl")
.addMatcherExactText("y")
.done()
.addReadConfigEvent()
.setType("header")
.setValueExactText("name", "Upgrade")
.addMatcherExactText("websocket")
.done()
.addReadEvent()
.addExactBytes(new byte[] {(byte) 0x82}, new ExpressionContext())
.done()
.addReadCloseCommand()
.done()
.addWriteConfigCommand()
.setType("status")
.setValue("code", "101")
.setValue("reason", "Switching Protocols")
.done()
.addWriteConfigCommand()
.setType("header")
.setName("name", "upgrade")
.addValue("websocket")
.done()
.addWriteCloseCommand()
.done()
.addCloseCommand()
.done()
.addClosedEvent()
.done()
.done()
.done();
// @formatter:on
assertEquals(expected, actual);
}
@Test
public void shouldParseHttpWriteRequestReadResponseScript() throws Exception {
// @formatter:off
String script =
"connect http://somehost:8000/path\n" +
"connected\n" +
"write method \"get\"\n" +
"write parameter \".kl\" \"y\"\n" +
"write header \"Upgrade\" \"websocket\"\n" +
"write close\n" +
"read status \"101\" \"Switching Protocols\"\n" +
"read header \"upgrade\" \"websocket\"\n" +
"read closed \n" +
"write [0x82]\n" +
"close\n" +
"closed\n";
// @formatter:on
ScriptParserImpl parser = new ScriptParserImpl();
AstScriptNode actual = parser.parseWithStrategy(script, SCRIPT);
AstLocation location = new AstLocationLiteral(URI.create("http://somehost:8000/path"));
// @formatter:off
AstScriptNode expected = new AstScriptNodeBuilder()
.addConnectStream()
.setLocation(location)
.addConnectedEvent()
.done()
.addWriteConfigCommand()
.setType("method")
.addValue("get")
.done()
.addWriteConfigCommand()
.setType("parameter")
.setName("name", ".kl")
.addValue("y")
.done()
.addWriteConfigCommand()
.setType("header")
.setName("name", "Upgrade")
.addValue("websocket")
.done()
.addWriteCloseCommand()
.done()
.addReadConfigEvent()
.setType("status")
.setMatcherExactText("code", "101")
.setMatcherExactText("reason", "Switching Protocols")
.done()
.addReadConfigEvent()
.setType("header")
.setValueExactText("name", "upgrade")
.addMatcherExactText("websocket")
.done()
.addReadCloseCommand()
.done()
.addWriteCommand()
.addExactBytes(new byte[] {(byte) 0x82})
.done()
.addCloseCommand()
.done()
.addClosedEvent()
.done()
.done()
.done();
// @formatter:on
assertEquals(expected, actual);
}
@Test
public void shouldParseHttpWithContent() throws Exception {
// @formatter:off
String script =
"accept http://somehost:8000/path\n" +
"accepted\n" +
"read method \"get\"\n" +
"read closed\n" +
"write status \"200\" \"OK\"\n" +
"write header content-length\n" +
"write \"some content\"\n" +
"write close \n";
// @formatter:on
ScriptParserImpl parser = new ScriptParserImpl();
AstScriptNode actual = parser.parseWithStrategy(script, SCRIPT);
// @formatter:off
AstScriptNode expected = new AstScriptNodeBuilder()
.addAcceptStream()
.setLocation(new AstLocationLiteral(URI.create("http://somehost:8000/path")))
.done()
.addAcceptedStream()
.addReadConfigEvent()
.setType("method")
.setMatcherExactText("name", "get")
.done()
.addReadCloseCommand()
.done()
.addWriteConfigCommand()
.setType("status")
.setValue("code", "200")
.setValue("reason", "OK")
.done()
.addWriteConfigCommand()
.setType("content-length")
.done()
.addWriteCommand()
.addExactText("some content")
.done()
.addWriteCloseCommand()
.done()
.done()
.done();
// @formatter:on
assertEquals(expected, actual);
}
}