<?xml version="1.0"?>
<!--
  Copyright 2002,2004 The Apache Software Foundation.
  
  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.
-->
<j:jelly
    xmlns:j="jelly:core"
    xmlns="jelly:jetty"
    xmlns:http="jelly:http"
    trim="false">

    <j:set var="contextPathVar" value="/resourceHandlerTest"/>
    <j:set var="testPort1" value="8100"/>
    <j:set var="testUri1" value="http://localhost:${testPort1}${contextPathVar}/resourceHandlerTest.txt"/>

    <jettyHttpServer var="httpServer">
      <socketListener port="${testPort1}"/>
      <httpContext contextPath="${contextPathVar}" resourceBase="./docRoot/resourceHandlerTest">
          <jellyResourceHandler>

            <postRequest>
                <!-- return the request body -->
                <responseHeader name="Content-Type" value="text/plain"/>
                <responseBody>
                    ${requestBody}
                </responseBody>
                <!-- also test response code -->
                <responseCode value="202"/>
            </postRequest>

          </jellyResourceHandler>
      </httpContext>
    </jettyHttpServer>

    <!-- post something -->
    <http:post var="mtc1" uri="${testUri1}">
        <http:header name="Content-Type" value="text/plain"/>
        <http:body>
            It works!
        </http:body>
    </http:post>

    <j:choose>
      <j:when test="${mtc1.statusCode == 202}">
          ${mtc1.responseBodyAsString}
      </j:when>

      <j:otherwise>
        Results for mtc1 url are:
        http return code = ${mtc1.statusCode}
        http status text = '${mtc1.statusText}'
      </j:otherwise>
    </j:choose>

    ${httpServer.stop(false)}

</j:jelly>
