Master_A2Z
Master_A2Z

Reputation: 97

Catching duplicate request headers with HttpServletRequest

I am running into a problem with HttpServlet request. I have an application in which it is to retrieve request headers. If the application finds duplicate header names, it's supposed to throw an error. However, after a bit of Googling, I found out that HttpServletRequest ignores duplicate header names, and proceeds with getting the first header name it encounters. Is there anything I can do to catch those duplicate request headers?

I'm using Tomcat 6 as the application container.

This is the code:

int headerChecker=0;
for(Enumeration<String>names = request.getHeaderNames(); names.hasMoreElements(); ) {
    String name = (String)names.nextElement();
    if(name.equalsIgnoreCase("abcd")){
        headerChecker++; // add 1 to headerChecker if abcd header is encountered
    }
    for(Enumeration<String>values = request.getHeaders(name); values.hasMoreElements(); ) {
        String value=(String)values.nextElement();
        System.out.println("name: "+name+"\tvalue: "+value);
        }
    }

    if(headerChecker! = 1){
        logger.error("abcd is duplicated, returning HTTP 404");
    } else {
        //...proceed with application
    }
}

Here is the log:

name:  host   value: localhost:8080  name: user-agent value:
CocoaRestClient/8 CFNetwork/520.4.3 Darwin/11.4.2 (x86_64)
(MacBookPro9%2C2)  name: content-length value: 23  name: accept   value:

**name: abcd  value: 1234556**  name: accept-language value: en-us  name: accept-encoding value: gzip, deflate  name: content-type    value:
application/x-www-form-urlencoded  name: connection value: keep-alive

This is the test screenshot:

enter image description here

Edit: Here is the servlet

public class HeaderServlet extends HttpServlet
{
public void doPost(HttpServletRequest req, HttpServletResponse res)
{
    doGet(req, res);
}

public void doGet(HttpServletRequest req, HttpServletResponse res)
{
int xmsisdnChecker = 0;
String value = "";  
for(Enumeration<String> names = req.getHeaderNames();names.hasMoreElements();){
    String name = (String) names.nextElement(); 
    Enumeration<String> values = req.getHeaders(name);
    if(values != null)
    {
        while(values.hasMoreElements()) {
            if(name.equalsIgnoreCase("abcd"))
            {
                xmsisdnChecker++;
                System.out.println("ee: " + xmsisdnChecker) ;
            }

            value = (String) values.nextElement();

            System.out.println("header name: " + name + "\theader value: " + value);
        }

    }   
  }
}   
}

Upvotes: 2

Views: 5533

Answers (3)

Gyan-Lucifer
Gyan-Lucifer

Reputation: 228

Do an inner loop after getting the header name.

    Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
        String headerName = headerNames.nextElement();
        Enumeration<String> headerValues = request.getHeaders(headerName);
        List<String> values = new ArrayList<>();
        
        // This will give you multiple values on the same key.
        while (headerValues.hasMoreElements()){
            values.add(headerValues.nextElement());
        }

        headers.put(headerName, values);
    }

Upvotes: 0

user207421
user207421

Reputation: 310913

Your increment is in the wrong place. HttpServletRequest collects all the values together and presents them as multiple values of a single header. You should test and increment headerChecker inside the inner loop where you loop over the values. The outer loop will only encounter 'abcd' once.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500535

No, HttpServletRequest doesn't ignore duplicate headers - it collects them.

From HttpServletRequest.getHeaders(String)

Returns all the values of the specified request header as an Enumeration of String objects.

Some headers, such as Accept-Language can be sent by clients as several headers each with a different value rather than sending the header as a comma separated list.

So it sounds like you just need to call getHeaderNames() to retrieve all of the headers that are present, then call getHeaders(String) with each name, and see whether the returned enumeration has more than one entry.

Upvotes: 7

Related Questions