How to log/debug bad requests in tomcat? - http

In our system (closed system, java web application in tomcat 6 as server, java fat clients) our clients show occasionally "400 - Bad Request" responses. I would like to debug this on the server side, but since the requests seem to be invalid, I don't see them anywhere. I configured the AccessLogValve for the complete tomcat host, but the requests don't appear there. I don't even see anything in catalina.out.
I would love to get these requests logged and even better would be to dump requests based on certain criteria.
Any ideas?
My server.xml looks like this:
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiServerPortPlatform="9098"
rmiRegistryPortPlatform="9099"
useLocalPorts="true" />
<Service name="Catalina">
<Connector port="8020" protocol="HTTP/1.1" redirectPort="8010" connectionTimeout="20000" />
<Engine name="Catalina" defaultHost="localhost" jvmRoute="cc1">
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false"
deployOnStartup="true" xmlValidation="false" xmlNamespaceAware="false">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="access_log."
suffix=".txt" pattern="combined" resolveHosts="false" />
</Host>
</Engine>
</Service>
</Server>

long time ago - but anyway: Tomcat has different Valves that may help to achieve that: http://tomcat.apache.org/tomcat-6.0-doc/config/valve.html#Request_Dumper_Valve
Another option would be tcpdump since it is HTTP and a response code it seems possible to filter the raw requests that cause this.

Related

Tomcat Configuration to host a webapp on different ports with different web.xml

I want to deploy my webapp with two different ports having two different deployment descriptors.
Is there a way to do so? I know how can I deploy a webapp on multiple ports. Wonder if we can provide separate deployment descriptor for an app being deployed on each connector.
<Service name="serviceA">
<Connector port="8080" maxHttpHeaderSize="8192" maxThreads="10"
enableLookups="false" acceptCount="100"
connectionTimeout="10000" disableUploadTimeout="true"
useBodyEncodingForURI="true"/>
<Engine name="serviceA" defaultHost="localhost" jvmRoute="host1">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
<Host name="localhost" appBase="webapps" unpackWARs="true"
autoDeploy="false" xmlValidation="false"
xmlNamespaceAware="false" xmlBase="PATH_TO_CUSTOM_web.xml">
<Context docBase="browser" path="/browser" reloadable="false"/>
</Host>
</Engine>
</Service>
<Service name="serviceB">
<Connector port="8081" maxHttpHeaderSize="8192" maxThreads="10"
enableLookups="false" acceptCount="100"
connectionTimeout="10000" disableUploadTimeout="true"
useBodyEncodingForURI="true"/>
<Engine name="serviceB" defaultHost="localhost" jvmRoute="host1">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
<Host name="localhost" appBase="webapps" unpackWARs="true"
autoDeploy="false" xmlValidation="false"
xmlNamespaceAware="false" xmlBase="PATH_TO_CUSTOM_web.xml">
<Context docBase="browser" path="/browser" reloadable="false"/>
</Host>
</Engine>
</Service>
Something like xmlBase="PATH_TO_CUSTOM_web.xml"
One can specify absolute path to the deployment descriptor instead of the default value.
altDDName
Ref: https://tomcat.apache.org/tomcat-8.5-doc/config/context.html

Sending Data over TCP on wso2 ESB

I have created a code where an external system can call wso2 esb over TCP and pass data, this is working fine without any issues however the reverse process is not happening and i am getting confused.
Here i would need to pass certain data to external system over TCP, however i am unable to do so as the parameters which are available while developing proxy doesn't contain IP address, it just contain port number, so i am curious as to how can the communication even be established when the IP address is not mentioned in the proxy.
Any help is appreciated.
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="TCPProxyClient"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<property name="symbol" scope="default" type="STRING" value="IBM"/>
<enrich>
<source clone="true" type="inline">
<m:getQuote xmlns:m="http://services.samples">
<m:request>
<m:symbol>?</m:symbol>
</m:request>
</m:getQuote>
</source>
<target type="body"/>
</enrich>
<enrich>
<source clone="true" property="symbol" type="property"/>
<target xmlns:m="http://services.samples" xpath="//m:getQuote/m:request/m:symbol"/>
</enrich>
<log level="full" separator=","/>
<send/>
</inSequence>
<outSequence>
<log level="full"/>
<send/>
</outSequence>
</target>
<parameter name="transport.tcp.responseClient">true</parameter>
<parameter name="transport.tcp.inputType">string</parameter>
<parameter name="transport.tcp.recordDelimiter">|</parameter>
<parameter name="transport.tcp.contentType">text/xml</parameter>
<parameter name="transport.tcp.port">8691</parameter>
<parameter name="transport.tcp.recordDelimiterType">character</parameter>
<description/>
</proxy>
The parameters above are used only when the proxy is listening for TCP messages. For sending a TCP message to a TCP socket, you need to define an endpoint in the send mediator.
<send>
<endpoint>
<address uri="tcp://localhost:8001/helloService"/>
</endpoint>
<send>
Follow the doc [1] to enable to TCP transport sender in axis2.xml.
Refer the question [2] for more info.

Port number 8443 is shown in the browser address bar when using Tomcat with HTTPS

I am working on a Spring MVC application and I have deployed that on a Tomcat installation on the server. In the configuration which I will post below of Tomcat and Spring, HTTP communication occurs on port 80 and HTTPS on port 8443.
Now when the application is deployed, I can see in the browser URL as
https://domainname.com:8443/nameOfPage
I don't want want to show the port number to the user. What should I do, kindly let me know.
Thank you.
Spring Security config.xml
<security:http create-session="ifRequired" use-expressions="true" auto-config="true" disable-url-rewriting="true">
<security:form-login login-page="/"
default-target-url="/canvas/list"
always-use-default-target="false"
authentication-failure-url="/denied.jsp" />
<security:remember-me key="_spring_security_remember_me"
user-service-ref="userDetailsService"
token-validity-seconds="1209600"
data-source-ref="dataSource" />
<security:logout logout-success-url="/"
delete-cookies="JSESSIONID"
invalidate-session="true"
logout-url="/j_spring_security_logout" />
<security:intercept-url pattern="/" requires-channel="https" access="permitAll" />
<security:intercept-url pattern="/canvas/list" access="hasRole('ROLE_USER')" requires-channel="https" />
<security:port-mappings>
<security:port-mapping http="80" https="443" />
</security:port-mappings>
</security>
Apache Tomcat server.xml:
<Connector port="80"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8443"
protocol="HTTP/1.1"
SSLEnabled="true"
maxThreads="150"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS"
keystoreFile="/path/to/keystore.jks"
keystorePass="password" />
The only way to achieve this is to use port 443 instead.
The browser will always tell you if you're using a non-standard port, and the standard port for HTTPS is 443.
Similarly, for HTTP if you use any port other than 80, the port number will show in the address bar.

Enabling gzip compression for Jboss

How is gzip compression for Jboss 5.1.0 enabled?
Within the tomcat http connector right? I cant remember where this file is stored, server.xml?
edit jboss\server\default\deploy\jbossweb.sar\server.xml
Edit this:
<Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}"
connectionTimeout="20000" redirectPort="8443" />
to be more like this:
<Connector protocol="HTTP/1.1" port="8080" address="${jboss.bind.address}" compression="on"
compressableMimeType="text/html,text/xml,text/css,text/javascript, application/x-javascript,application/javascript"
connectionTimeout="20000" redirectPort="8443" />
You can refer to connector config info for further details please see:
http://tomcat.apache.org/tomcat-5.5-doc/config/http.html
To add gzip compression in JBoss 7.1.1, you can edit standalone/configuration/standalone.xml and add:
...
</extensions>
<system-properties>
<property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION" value="on"/>
<property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIME_TYPES" value="text/javascript,text/css,text/html"/>
</system-properties>
Restart the server and check with developer tools or in the HTTP header if it is enabled.
The file is under server.xml and you are correct in stating that you have to updated the http connector.
Following link is info for tomcat, but same applies to JBoss except location of server.xml file. I believe you need to update the server.xml under deploy\jbossweb.sar\
http://viralpatel.net/blogs/2008/11/enable-gzip-compression-in-tomcat.html
In Jboss EAP 7.0 this worked for me:
edit: Standalone.xml
<subsystem xmlns="urn:jboss:domain:undertow:1.2"> <!-- SEARCH FOR THIS: urn:jboss:domain:undertow -->
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http"/>
<host name="default-host" alias="localhost">
(...)
<!-- ADD THIS FOR GZIP COMPRESSION -->
<filter-ref name="gzipFilter" predicate="exists['%{o,Content-Type}'] and regex[pattern='(?:application/javascript|text/css|text/html|text/xml|application/json)(;.*)?', value=%{o,Content-Type}, full-match=true]"/>
<!-- /GZIP COMPRESSION -->
</host>
</server>
(...)
<filters>
(...)
<!-- ADD THIS FOR GZIP COMPRESSION -->
<gzip name="gzipFilter"/>
<!-- /GZIP COMPRESSION -->
</filters>
</subsystem>
Restart the server

Can I programmatically define my IIS7 site-bindings (eg. foo.domain.com)?

for my IIS7 website, i've had to go into the IIS7 Services Manager and define all the bindings for the site. Works fine.
I was wondering if it's possible to do this programatically in the web.config file instead? I know you can provide a few iis7 settings in there.. wasn't sure if it's possible to also include the bindings?
eg.
http; all unassigned ip's; port 80; foo.domain.com
https; 192.168.0.2; port 443; blah.domain.com
The configuration is found in the config file of the parent applicationHost.config, however I'm not sure it can be overridden. For example in IIS Express the section you are looking for is:
<system.applicationHost>
...
<sites>
<site name="Development Web Site" id="1" serverAutoStart="true">
<application path="/">
<virtualDirectory path="/" physicalPath="%IIS_BIN%\AppServer\empty_wwwroot" />
</application>
<bindings>
<binding protocol="http" bindingInformation=":8080:localhost" />
</bindings>
</site>
<siteDefaults>
<logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
<traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
</siteDefaults>
<applicationDefaults applicationPool="IISExpressAppPool" />
<virtualDirectoryDefaults allowSubDirConfig="true" />
</sites>
</system.applicationHost>
You could try running (sorry - I haven't tried any of these myself):
%windir%\system32\inetsrv\appcmd.exe unlock config -section:system.applicationHost
But from a security point of view it doesn't make sense to allow web.configs to each individually mess with system.applicationHost, as one site's config could break every other site.
Look at the Microsoft.Web.Administration namespace. you can then configure and maniuplate most of IIS 7 from C# code.
there is also a utility Appcmd that allows you to manipulate almost everything in IIS 7.0. be warned that this tool has tons of options and switches. I have only used it for the most basic of tasks such as changing physical directories on applications.

Resources