Showing posts with label IIS. Show all posts
Showing posts with label IIS. Show all posts

Friday, August 02, 2013

Tomcat IIS Connector "request entity is too large"

Keywords:
tomcat IIS IIS7 jk connector max_packet_size packetSize "The page was not displayed because the request entity is too large"

Problem:
With IIS successfully configured with tomcat using the Apache Tomcat Connector (aside: if you haven't got that far the IIS Admin Blog - How To Configure IIS 7.0 and Tomcat is a good reference - with screenshots) you find that some users can access the web-apps ok, others cannot. They get a plain error page saying:
The page was not displayed because the request entity is too large
How do you fix it?

Solution:
The issue is with attributes in the request exceeding the AJP 8kb default (for me, the ISAPI redirector was logging the error was with the 'Authorization' attribute). You can increase this to maximum of 65Kb.

This needs to be done in the tomcat-connector and tomcat itself.

Step 1: Set max_packet_size in the worker definition

In the workers.properties file referenced by the tomcat-connection definition, set the packet size to the maximum:
worker.<worker name>.max_packet_size=65536
for example:
worker.ajp13w.max_packet_size=65536
Check the workers documentation for more information.

Step 2: Set packetSize in the AJP Connector definition

In the server.xml configuration file for tomcat, set the packet size to the maximum:
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" packetSize="65536"
        tomcatAuthentication="false" />
Check the AJP Connector documentation for more information.


You'll then need to restart tomcat and IIS Site for the changes to take effect (then hope for the best).

Tuesday, April 05, 2011

IIS7 hiding tomcat webapp error pages

Keywords:
IIS IIS7 custom error pages hiding masking tomcat 500 webapp error page jk connector AJP

Problem:
With tomcat integrated into IIS7 using the jk connector error pages from the webapp that have the http-response status set (eg to 500) get "replaced" with a generic IIS custom error page:
500 - Internal server error. 
There is a problem with the resource you are looking for, and it cannot be displayed


A quick web-search reveals it's a common issue for ASP.NET developers and the solution is simply to make changes to the ASP.NET application config or in code setting a special HttpResponse.TrySkipIisCustomErrors property(!) ... but what are the options for when the pages are being supplied by an ISAPI redirector/plugin (i.e. the JK connector in this case)?

Solution:
Based on the detailed notes on the IIS Blog (What to expect from IIS7 custom error module) the minimal steps required seem to be the following:

Step 1: create a Web.config file in the root folder of the Web Site


This is the Web Site where you've configured the "jakarta" virtual directory. If it's "Default Web Site" this may be C:\inetpub\wwwroot but check the properties to be sure (Right click Web Site > Manage Web Site > Advanced Settings ... and note the setting for 'Physical Path').

Step 2: add configuration to the Web.config file


<configuration>
   <system.webServer>
      <httpErrors errorMode="Detailed" existingResponse="Auto" />
   </system.webServer>
</configuration>


Step 3: restart the web site


Eg Right click Web Site > Manage Web Site > Restart


Be sure to to test this on the local machine (where IIS7 is installed) and from another machine in the network as IIS may give different error-page behaviour for local and 'remote' requests.

Tuesday, March 08, 2011

NTLM from an Axis (SOAP) service client - in 3 steps

Keywords:
NTLM authentication Negotiate Apache axis SOAP IIS Windows Integrated Authentication CommonsHTTPSender NTCredentials

Problem:
Authenticating a service request with BASIC authentication is (relatively) straightforward:

import java.net.URL;
import org.apache.axis.client.Stub;
import com.example.service.Example;
import com.example.service.ExampleServiceLocator;
import com.example.service.ExampleRequest;
import com.example.service.ExampleResponse;

// get access to the web service
ExampleServiceLocator locator = new ExampleServiceLocator();
String serviceURL = "http://server/application/services/example";
Example example = locator.getexample(new URL(serviceURL));
// set credentials
((Stub)example).setUsername("myusername");
((Stub)example).setPassword("mypassword");


// setup request
ExampleRequest request = new ExampleRequest();
request.setProperty("SomeProperty");

ExampleResponse response = example.example(request);


What if the (SOAP) service being called required NTLM authentication (e.g. the service is running in IIS and security is set as "Windows Integrated Authentication")?

Solution:
The following three steps are assuming Axis 1.x. The Apache Axis Client Tips and Tricks is a good reference, in particular for step 2, but also for other "tips".

Step 1: Add Apache commons-httpclient (3.1) and commons-codec libraries


Note you must add the commons httpclient jar file and not the (latest/refactored) apache httpclient to the project - or you will get ClassNotFound exceptions.

Step 2: Define custom client-config with CommonsHTTPSender


It's mentioned in the "Tips and Tricks" article mentioned above, but you can either: (a) define a custom client-config.wsdd file in the classpath before axis.jar; (b) edit the generated ...ServiceLocator.java generated class and make it override getEngine...; or (c) at runtime simply feed the customised config XML to your ...ServiceLocator object.

I prefer the latter - for example, define a static method with the config XML as a string:

protected static org.apache.axis.EngineConfiguration getEngineConfiguration() {
java.lang.StringBuffer sb = new java.lang.StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
sb.append("<deployment name=\"defaultClientConfig\"\r\n");
sb.append("xmlns=\"http://xml.apache.org/axis/wsdd/\"\r\n");
sb.append("xmlns:java=\"http://xml.apache.org/axis/wsdd/providers/java\">\r\n");
// sb.append("<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.HTTPSender\" />\r\n");
sb.append("<transport name=\"http\" pivot=\"java:org.apache.axis.transport.http.CommonsHTTPSender\" />\r\n");
sb.append("<transport name=\"local\" pivot=\"java:org.apache.axis.transport.local.LocalSender\" />\r\n");
sb.append("<transport name=\"java\" pivot=\"java:org.apache.axis.transport.java.JavaSender\" />\r\n");
sb.append("</deployment>\r\n");
org.apache.axis.configuration.XMLStringProvider config =
new org.apache.axis.configuration.XMLStringProvider(sb.toString());
return config;
}


Then the call to the locator would become:

// get access to the web service
ExampleServiceLocator locator = new ExampleServiceLocator(getEngineConfiguration());


Step 3: Set the username as DOMAIN\username


Set the username as you did with BASIC authentication but you must ensure is set in the form DOMAIN\username (keeping in mind that if expressing this in java code - as a string - or as a property value in a properties file this would be set as "DOMAIN\\username" - \\ being the escape sequence for \):

((Stub)example).setUsername("MY_NT_DOMAIN\\myusername");
((Stub)example).setPassword("mypassword");


With the above 3 steps covered you're using NTLM.

Notes:
Avoid setting the system property -Djava.ext.dirs as the above relies on the sunjce_provider.jar library which is in JRE_HOME\lib\ext by default. Ext-path problems may give you errors such as:
"Cannot find any provider supporting DES/ECB/NoPadding"


Failing to set the username in the form DOMAIN\username will result in the error:
org.apache.commons.httpclient.auth.InvalidCredentialsException: 

Credentials cannot be used for NTLM authentication:
org.apache.commons.httpclient.UsernamePasswordCredentials
at org.apache.commons.httpclient.auth.NTLMScheme.authenticate(NTLMScheme.java:332)
at org.apache.commons.httpclient.HttpMethodDirector.authenticateHost(HttpMethodDirector.java:282)
at org.apache.commons.httpclient.HttpMethodDirector.authenticate(HttpMethodDirector.java:234)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.axis.transport.http.CommonsHTTPSender.invoke(CommonsHTTPSender.java:186)
This is because the format of the username determines the Credentials instance created. With the DOMAIN\... prefix on the username you get an instance of org.apache.commons.httpclient.NTCredentials rather than org.apache.commons.httpclient.UsernamePasswordCredentials - which as the message explains can't be used for NTLM.

Wednesday, November 15, 2006

IIS not streaming PDF

Keywords:
IIS 6.0 not streaming PDF IE

Problem:
As is the theme for many of these posts. The setup is IIS -> ISAPI/JK -> Tomcat. The application running on Tomcat is generating PDF. If you access the application directly via Tomcat the PDF content is returned fine - ie. Opens via the Adobe Reader plugin in IE. If you access the application via IIS you get a blank page in IE. All other formats work fine.

Solution:
The problem in this case was a setting in IIS that zips the content it's serving up. This is fine for HTML as browsers recognise this and unzip. For the Adobe PDF reader, the content is not expected to be compressed - hence the blank page, it doesn't know what to do (but an error message would have helped).

In IIS Manager, right click on the folder "Web Sites" and choose Properties. Click the "Services" tab.

You need to make sure HTML Compression is turned off. I’m not sure about the IIS 5.0 isolation setting ...

Restart IIS – right click the server (above the Web Sites folder) and choose All Tasks > Restart IIS ...

Select the "Restart Internet Services on YOUR-SERVER" option. It will only take only a few seconds (rather than 300).

Tuesday, November 14, 2006

Can't start IIS "World Wide Web Publishing Service" Error 126

Keywords:
Could not start IIS "World Wide Web Publishing Service" "Error 126"

Problem:
Trying to manually start the WWW service for IIS gives the following message:
"ERROR 126: The specified module could not be found."

The "World Wide Web Publishing Service" goes back to a stopped status. While this service is stopped, in the IIS Manager, the Web Sites folder is marked with an X and none of the Web Sites can be started.

Solution:
Need to check the Event Logs (Start > Programs > Administrative Tools > Event Viewer)

Clicking on the Application section shows a number of Errors. The most recent two errors were the most relevant:
  • Could not load all ISAPI filters for site/service. Therefore startup aborted.

  • The HTTP Filter DLL C:\[path to a DLL that no longer exists] failed to load. The data is the error.
I had to go into IIS Manager. View the ISAPI Filters (right click the Web Sites Folder > Properties > ISAPI Filters) and remove the filter that was referencing this DLL.

Going back to services, the WWW Publishing Service then starts fine.