Problem:
http://www.alphagalileo.org/rss_channels/?feed=all . This URL uses redirect.
The redirect happens in this way:

GET /rss_channels/?feed=all HTTP/1.0

User-Agent: Wget/1.10.2 (Red Hat modified)

Accept: */*

Host: www.alphagalileo.org

Connection: Keep-Alive



HTTP/1.1 307 Temporary Redirect

Connection: close

Date: Thu, 04 Sep 2008 08:25:16 GMT

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

Set-Cookie: CFID=4574600;expires=Sat, 28-Aug-2038 08:25:16 GMT;path=/

Set-Cookie: CFTOKEN=67833421;expires=Sat, 28-Aug-2038 08:25:16 GMT;path=/

location: http://www.alphagalileo.org/rss_channels/all.xml

Content-Type: text/html; charset=UTF-8

(i just recorded the http traffic with wireshark)

wget handles http response header field names differently as Drupal does. (see resp_header_locate in http.c at wget source code)

Drupal treats these field names case sensitive, wget does the opposite. I read the RFC 2616, but it's not clear me that Drupal does or does not follow the RFC in the question. But for practical reasons it should work as wget.

I attached a patch to fix this issue. It basically makes all the header field names lowercase and fix the places in drupal core where it matters.

Comments

dries’s picture

Let's write a simpletest for this?

aron novak’s picture

I wrote a test for this bug. I re-rolled the patch, now it contains the test too.

aron novak’s picture

I rerolled the patch to make it apply without any notices.

Status: Needs review » Needs work

The last submitted patch failed testing.

lilou’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch failed testing.

aron novak’s picture

Status: Needs work » Needs review
StatusFileSize
new6.31 KB

Rerolled against HEAD.

Status: Needs review » Needs work

The last submitted patch failed testing.

mr.baileys’s picture

Drupal treats these field names case sensitive, wget does the opposite. I read the RFC 2616, but it's not clear me that Drupal does or does not follow the RFC in the question. But for practical reasons it should work as wget.

Message header field names are case insensitive (see Message Headers in RFC 2616), so it looks like wget got it right:

HTTP header fields, which include general-header (section 4.5), request-header (section 5.3), response-header (section 6.2), and entity-header (section 7.1) fields, follow the same generic format as that given in Section 3.1 of RFC 822 [9]. Each header field consists of a name followed by a colon (":") and the field value. Field names are case-insensitive. The field value MAY be preceded by any amount of LWS, though a single SP is preferred.

I'm confused about the patch though:

I attached a patch to fix this issue. It basically makes all the header field names lowercase and fix the places in drupal core where it matters.

If we just established that header field names are case insensitive, then why are we changing the case of these field names, especially since the RFC uses capitalized field names itself (for example: If-Modified-Since)? Note: I'm not saying it's the wrong approach, I'm just not sure I fully understand the problem.

aron novak’s picture

Well, you can do the strtolower() at every comparison, but this sucks. I think the right approach is to use it always lower-case in Drupal (except when we issue a request) and use strtolower() only when parsing the http requests.
I have to take a look why the patch failed.

mr.baileys’s picture

I looked closer at your patch and the test and think I now understand the problem a bit better. I also agree that using strtolower() or strcasecmp() isn't the most elegant solution. I can't shake off the feeling that the proposed patch treats the symptoms rather than the actual problem though, but I understand your reasoning.

And now on to the actual patch:

  1.      if (isset($result->headers[$header]) && $header == 'Set-Cookie') {
           // RFC 2109: the Set-Cookie response header comprises the token Set-
           // Cookie:, followed by a comma-separated list of one or more cookies.
    -      $result->headers[$header] .= ',' . trim($value);
    +      $result->headers[strtolower($header)] .= ',' . trim($value);
         }
    

    I think this can become a bit messy: if I'm not mistaken, we can end up with two values, $result->headers['Set-Cookie'] and $result->headers['set-cookie'] which have different values?

  2. If we're forcing the result headers to lowercase, I feel we should at least document this, both at the PHPDoc for drupal_http_request:
     *   - headers
     *       An array containing the response headers as name/value pairs.
    

    as well as when the actual lowercase conversion happens.

c960657’s picture

I can't shake off the feeling that the proposed patch treats the symptoms rather than the actual problem though, but I understand your reasoning.

Well, I think the actual problem is that PHP doesn't support an array-like datatype with case-insensitive keys. The strtolower() approach is also used in SimpleTest in DrupalWebTestCase::drupalGetHeaders().

-    $headers['If-None-Match'] = $feed->etag;
+    $headers['if-none-match'] = $feed->etag;

This changes headers that are sent by drupal_http_request(). There is no need to lower-case them. It is only received headers that should be lower-cased.

c960657’s picture

Status: Needs work » Needs review
StatusFileSize
new7.78 KB

Updated patch.

Status: Needs review » Needs work

The last submitted patch failed testing.

c960657’s picture

Status: Needs work » Needs review
StatusFileSize
new7.78 KB

Ahem.

Status: Needs review » Needs work

The last submitted patch failed testing.

c960657’s picture

Status: Needs work » Needs review
StatusFileSize
new8.13 KB

It's been a while, but here is a reroll.

c960657’s picture

StatusFileSize
new8.13 KB

Reroll.

c960657’s picture

StatusFileSize
new8.11 KB

Reroll.

c960657’s picture

StatusFileSize
new8.12 KB

Reroll.

damien tournoud’s picture

Status: Needs review » Reviewed & tested by the community

RTBC if the bot passes.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, drupal_http_request-6.patch, failed testing.

c960657’s picture

Status: Needs work » Needs review

#20: drupal_http_request-6.patch queued for re-testing.

c960657’s picture

Status: Needs review » Reviewed & tested by the community

RTBC as per #21.

dries’s picture

Can we add a code comment that references the RFC (see comment #9)?

c960657’s picture

StatusFileSize
new8.22 KB

Added a reference to RFC 2616 in the Doxygen comment.

dries’s picture

Status: Reviewed & tested by the community » Fixed

Thanks a lot. Committed to CVS HEAD.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.