Setting custom HTTP request headers in an URL object doesn't work

13,602

Solution 1

Issue resolved. It didn't work because I was passing url to ImageIO.read().

Instead, passing uc.getInputStream() got it working.

Solution 2

In class sun.net.www.protocol.http.HttpURLConnection, which extends java.net.HttpURLConnection, the following method getRequestProperty(String key) was overridden to return null when requesting security sensitive information.

public String getRequestProperty(String key) {
    // don't return headers containing security sensitive information
    if (key != null) {
        for (int i = 0; i < EXCLUDE_HEADERS.length; i++) {
        if (key.equalsIgnoreCase(EXCLUDE_HEADERS[i])) {
            return null;
        }
        }
    }
    return requests.findValue(key);
}

Here is the declaration for EXCLUDE_HEADERS:

// the following http request headers should NOT have their values
// returned for security reasons.
private static final String[] EXCLUDE_HEADERS = {
    "Proxy-Authorization", "Authorization" };

That's why you're having a null on uc.getRequestProperty("Authorization"). Have you tried using HttpClient from Apache?

Share:
13,602
Blagovest Buyukliev
Author by

Blagovest Buyukliev

Author of Quaint, an experimental statically-typed imperative language with first-class resumable functions. Dedicated to the pursuit of clean, elegant and no-nonsense code.

Updated on June 09, 2022

Comments

  • Blagovest Buyukliev
    Blagovest Buyukliev almost 2 years

    I am trying to fetch an image from an IP camera using HTTP. The camera requires HTTP basic authentication, so I have to add the corresponding request header:

    URL url = new URL("http://myipcam/snapshot.jpg");
    URLConnection uc = url.openConnection();
    uc.setRequestProperty("Authorization", 
      "Basic " + new String(Base64.encode("user:pass".getBytes())));
    
    // outputs "null"
    System.out.println(uc.getRequestProperty("Authorization"));
    

    I am later passing the url object to ImageIO.read(), and, as you can guess, I am getting an HTTP 401 Unauthorized, although user and pass are correct.

    What am I doing wrong?

    I've also tried new URL("http://user:pass@myipcam/snapshot.jpg"), but that doesn't work either.

  • Blagovest Buyukliev
    Blagovest Buyukliev almost 13 years
    Thank you, now I understand the reason for getting null. But why does it return HTTP 401? Is it possible that the "Authorization" property is not set at all?
  • Blagovest Buyukliev
    Blagovest Buyukliev almost 13 years
    I tried HttpURLConnection uc = (HttpURLConnection) url.openConnection(), but the outcome is the same. My problem is not actually with getRequestProperty, but with the unsent Authorization header.
  • William Niu
    William Niu almost 13 years
    then perhaps override the openConnection method?
  • Buhake Sindi
    Buhake Sindi almost 13 years
    @Blagovest Buyukliev, if uc extends HttpURLConnection then typecast it to HttpURLConnection and get the InputStream of the error by calling getErrorStream(). That contains the message of the HTTP 401 error. Other than that, I can't help you.