3
votes

Let me start off by saying this was working yesterday, so I'm totally confused as to why it stopped working all of a sudden. And Java / Plugins are really not my specialty.

I'm working on an application that makes POST and GET calls to a server on another domain. This is a Maven Project. To avoid the Cross-Origin issues I have a httpproxy.ProxyServlet plugin.

I'm going to list all the working peices here, but basically the question and error are summed up at the bottom of this post.

pom.xml

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.mitre.dsmiley.httpproxy</groupId>
        <artifactId>smiley-http-proxy-servlet</artifactId>
        <version>1.6</version>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0.2</version>
            <configuration>
                <source>1.5</source>
                <target>1.5</target>
            </configuration>
        </plugin>
        <!--        War plugin below is required for above plugin to build project without errors.    http://stackoverflow.com/questions/7539970/cannot-construct-org-apache-maven-plugin-war-util-webappstructure-as-it-does-not-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
        </plugin>
    </plugins>

web.xml

The second servlet section is the one in question. I only post the first because the first works fine. for reference.

<servlet>
    <servlet-name>ad_auth</servlet-name>
    <servlet-class>org.mitre.dsmiley.httpproxy.ProxyServlet</servlet-class>
    <init-param>
        <param-name>targetUri</param-name>
        <param-value>${authserver}/aaenroll/rest/authContext</param-value>
    </init-param>
    <init-param>
        <param-name>log</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>ad_auth</servlet-name>
    <url-pattern>/adauth</url-pattern>
</servlet-mapping>


<servlet>
    <servlet-name>user_profile</servlet-name>
    <servlet-class>org.mitre.dsmiley.httpproxy.ProxyServlet</servlet-class>
    <init-param>
        <param-name>targetUri</param-name>
        <param-value>${authserver}/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}</param-value>
        <!--<param-value>${authserver}/aaenroll/rest/userProfile/userName/segotac.json?user=segotac</param-value>-->
    </init-param>
    <init-param>
        <param-name>log</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>user_profile</servlet-name>
    <url-pattern>/userProfile</url-pattern>
</servlet-mapping>

Javascript Ajax call

function checkEnrollment() {
var username = Cookies.get('username');
var authToken = Cookies.get('authToken');
$.ajax({
    type: "GET",
    beforeSend: function(request)
    {
        request.setRequestHeader("Authorization", authToken);
    },
    url: "userProfile?_username=" + username, //**PROBLEM HERE** -> Url intercepted by servlet plugin. Full path mapping is available in web.xml. As per the Plugin syntax, param _username will replace all "{_username}" in web.xml userProfile targetUri param-values.
    success: function(msg, success) {
        window.location.replace("enroll.jsp");
    },
    error: function(xhr, ajaxOptions, thrownError) {
        console.log('false Enrollment');
    }
});

Syntax for how the intercepted URL being passed in above is located at the bottom of this link. Which is the plugin. Which again... was working yesterday... https://github.com/mitre/HTTP-Proxy-Servlet

And at long last. The Error:

<html><head><title>Apache Tomcat/7.0.39 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - Trying to process targetUri init parameter: java.net.URISyntaxException: Illegal character in path at index 71: http://cslxintwebdev3.csmc.edu:8087/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}</h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u>Trying to process targetUri init parameter: java.net.URISyntaxException: Illegal character in path at index 71: http://cslxintwebdev3.csmc.edu:8087/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}</u></p><p><b>description</b> <u>The server encountered an internal error that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>javax.servlet.ServletException: Trying to process targetUri init parameter: java.net.URISyntaxException: Illegal character in path at index 71: http://cslxintwebdev3.csmc.edu:8087/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}
org.mitre.dsmiley.httpproxy.ProxyServlet.initTarget(ProxyServlet.java:156)
org.mitre.dsmiley.httpproxy.ProxyServlet.init(ProxyServlet.java:140)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:722)

root cause

java.net.URISyntaxException: Illegal character in path at index 71: http://example.com:8087/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}
    java.net.URI$Parser.fail(URI.java:2829)
    java.net.URI$Parser.checkChars(URI.java:3002)
    java.net.URI$Parser.parseHierarchical(URI.java:3086)
    java.net.URI$Parser.parse(URI.java:3034)
    java.net.URI.<init>(URI.java:595)
    org.mitre.dsmiley.httpproxy.ProxyServlet.initTarget(ProxyServlet.java:154)
    org.mitre.dsmiley.httpproxy.ProxyServlet.init(ProxyServlet.java:140)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:947)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1009)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    java.lang.Thread.run(Thread.java:722)

note The full stack trace of the root cause is available in the Apache Tomcat/7.0.39 logs.

Apache Tomcat/7.0.39

So the short question is, why is the username param being sent to the HttpProxy plugin not being intercepted and replaced correctly?

Sorry if this is way to much info to throw at this. Hopefully someone who is familiar with these technologies will be able to quickly identify the issue or point me on the correct debugging path.

THANK ALOOOT!

Edit

web.xml

<servlet-class>org.mitre.dsmiley.httpproxy.URITemplateProxyServlet</servlet-class>
<url-pattern>/userProfile/*</url-pattern>

js

url: "userProfile?_username=" + username,

Error:

HTTP Status 500 - Missing HTTP parameter _username to fill the template

I know username has a value in the javascript call. Variable is not being applied correctly to the template in web.xml

Thanks again!

2
Missing $ sign from username? (instead of {_username} should not it be ${_username} in web.xml?) - skandigraun
its not a jQuery variable. which is the only reason I'm aware of that syntax. Also, the example at the bottom of the Plugin page outlining how to write the parameterized proxy URL shows no $'s on variables - csegota
print var username in javascript - what's its value? - ZhongYu
username variable is populated correctly in the javascript. it get lost somewhere in the interception by the plugin. - csegota

2 Answers

1
votes

It is mainly a problem with your servlet mapping. Per the documentation, I don't see any indication that class ProxyServlet allows for parameterization (though maybe it does). Perhaps you should use class URITemplateProxyServlet instead. You would change your servlet definition as such:

<servlet-class>org.mitre.dsmiley.httpproxy.URITemplateProxyServlet</servlet-class>
<init-param>
    <param-name>targetUri</param-name>
    <param-value>{authserver}/aaenroll/rest/userProfile/userName/{_username}.json?user={_username}</param-value>
    ...

and the servlet mapping as such, (notice the '*'):

<servlet-mapping>
  <servlet-name>user_profile</servlet-name>
  <url-pattern>/userProfile/*</url-pattern>
</servlet-mapping>

Then in your ajax:

...
url: "userProfile/?authserver=" + authserver + "&_username=" + username;
...

So I was reading the source for URITemplateProxyServlet and I think it might be expecting a one to one matching of args. In other words, for every argument in the targetUri, there must be a matching argument in the querystring (i.e. the URL your ajax generates). Unfortunately I can't test, but you should be able to tell quickly if this is the fact.

Try this:

  • To avoid confusion set the url-pattern to have a second '/' as such <url-pattern>/userProfile/*</url-pattern> just as their documentation does.
  • Change the ajax generated URL to match this pattern AND have a second param as such : "userProfile/subpath?_username=" + username + "&_username2=" + username;
  • Change your target uri as necessary: <param-value>${authserver}/aaenroll/rest/userProfile/userName/{_username}.json?user={_username2}</param-value>
0
votes

Well, I finally figured out what the issue was. Since I was trying to use the same _username param to fill in TWO spots in my targetUri, one of them was getting lost. Basically you cant apply the same param twice to the targetUri using this plugin.

Solution: web.xml

<servlet>
    <servlet-name>user_profile</servlet-name>
    <servlet-class>org.mitre.dsmiley.httpproxy.URITemplateProxyServlet</servlet-class>
    <init-param>
        <param-name>targetUri</param-name>
        <param-value>${authserver}/aaenroll/rest/userProfile/userName/{_username}.json?user={_username2}</param-value>
    </init-param>
    <init-param>
        <param-name>log</param-name>
        <param-value>true</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>user_profile</servlet-name>
    <url-pattern>/userProfile/*</url-pattern>
</servlet-mapping>

ajax call

$.ajax({
    type: "GET",
    beforeSend: function(request)
    {
        request.setRequestHeader("Authorization", authToken);
    },
    url: "userProfile?_username=" + username + "&_username2=" + username;, //Url intercepted by servlet plugin. Full path mapping is available in web.xml
    success: function(msg, success) {
    },
    error: function(xhr, ajaxOptions, thrownError) {
    }
});