Feeds that are protected by securesite are not accessible by readers like NetNewswire and even the drupal feedAPI module. This is due to the drupal_goto code wich generates a 302 redirect. Not all news fetchers/readers support cookies for a multiple requests. And some readers just don't like redirects.

Please reference http://drupal.org/node/23038 for some background.

This bug was fixed and crept back in to fix a page caching issue. Fair enough. I'm just ondering if there is any other way to make this all work? FeedAPI is very cool and could be amazing if it worked with securesite for content publishers.

Not sure if this is fixable, but any ideas or suggestions are appreciated.

Comments

darren oh’s picture

See CVS commit 138632. Nax and Junyor: Was this a browser-specific problem?

chrisschaub’s picture

Also, this drupal_goto appears in the code for regular authenticated users, causing the same problem.

junyor’s picture

chrisschaub’s picture

Sorry, it didn't work. NetNewsWire (Mac RSS client) complains about the 302 redirect from the drupal_goto.

"NetNewsWire can’t open the page ‘’ because of an error: Operation could not be completed. (kCFErrorDomainCFNetwork error 302."

I'm assuming feedAPI (Drupal mod) is having the same problem. I also think the problem is related to the COOKIE not being availabe on rss clients for the redirected request. I tried forcing a 200 in drupal_goto -- no luck.

TESTED FIX: Removing the drupal_goto and replacing with a "return" works fine, the readers can authenticate and get the data. I'm assuming the goto is to prevent returning a cached page?

Is there a way to not use drupal_goto, create a similar function that passes the base64 auth credentials to the new location? I think anything other than response code 200 will be problematic. I'm really not sure if it's a COOKIE or 302 issue at this point. Maybe a combo of both. It could also be than any type of redirect is a problem. Is there a way to prevent the caching problem?

I've seen this on Drupal 5 and 6. Currently testing on latest 6.

Thanks for your help!

junyor’s picture

That fix was a work-around for the following issue reported via e-mail by NaX:

1. Make site partially protected by securesite
2. Login as guest by going to a securesite protected page
3. Login as a normal user using drupal login block
4. Logout user
5. Go to guest page (page that requires securesite authentication)

Because the auth variables were never cleared the user is shown the guest page again without requiring to re-authenticate again. Step 4 should have shown the auth dialog to clear the auth variables of the guest username and password.

chrisschaub’s picture

Isn't there a way to unset any guest session variables before logging in a real drupal user, just in case? This drupal_goto isn't a good fix for the previous problem because it renders feed readers unable to fetch data protected by securesite.

Looking at code for a solution ... tricky stuff.

junyor’s picture

That's already being done. See line 292. As soon as we determine that the user isn't a guest, the guest session is unset as a precaution.

However, I'm beginning to think that it's the redirect on line 317, not the redirect on 290, that's causing this problem. It looks like that fixes another caching problem that would occur in the following circumstances:

1) Login as a guest
2) Close the Drupal site
3) Delete the Drupal session cookie
4) Restart your browser to reset the HTTP Auth variables
5) Login as a privileged user

At this point, you'll get the guest's cached page. If you reload, you get the privileged user's page.

chrisschaub’s picture

Yes, it's line 317 that's the problem for regular Drupal users trying to read feeds. Line 290 is also a problem if you want to allow guest users access to feeds. Sorry for not being clear. These line numbers are for the Drupal 5 version. For Drupal 6, the real problem area is line 186 and 166 respectively.

Isn't the scenario you mention really a browser problem? If you aren't caching pages in your browser, then will give drupal still give you a cached page? Is there a way to clear the cache or only use the drupal_goto if caching is enabled?

junyor’s picture

Maybe we can override the $_REQUEST variable as indicated in http://api.drupal.org/api/function/drupal_goto/5 to pass the auth variables. But I'm not positive that will help. If the user isn't logged in (which they won't be since no cookie is set), Secure Site will process the login again, which will redirect again.

junyor’s picture

The only solution I can think of is to find a different work-around for the caching problems. NaX and I have already spent a significant amount of time finding the current solution after exhausting many possibilities. If you can find a different solution that passes all the unit tests, I'll gladly evaluate it.

chrisschaub’s picture

In the short term, can we only call drupal_goto if caching is enabled? Then a note could be put in the doc about caching not being compatible with securing feeds.

junyor’s picture

That won't fix the problem from comment #5 and I don't really want to complicate the code with partial work-arounds.

chrisschaub’s picture

Ok, I'll try to work on a real fix. I need to spend some time reading the code. Thanks for your help.

chrisschaub’s picture

I'm going to suggest something, and I hope it doesn't make anyone too mad! :?) Just for consideration after perusing the code a bit ....

1. Is the problem that drupal_goto is trying to solve a greater bug than blocking access to all RSS feeds by feed readers? It just seems that the use case mentioned in #5 above involves a user that has access to a guest and regular drupal login. Is there a great harm in them seeing the guest page for one page load after they've logged out of their regular account? Furthermore, who is going to do this, I mean login as a guest and then login as a regular user. Seems like a very isolated incident whose effects are quite harmless -- after all, the user was once logged in as a guest and saw the content. Is it such a big deal that they see a cached page of the same content in this isolated case?

2. Why does this module need a "guest" account? You can very easily create a guest account in Drupal using the regular access control system. Then, drupal will be handling all logins, sessions etc. No need for special code to handle guests in securesite. I guess I'm wondering if two authentication schemes are ever a good idea, especially when you can achieve the same result with one?

3. One option would be to check if the guest account is enabled. If it's not, not need to drupal_goto. I don't see this as a hack but rather a sensible compromise, to get feeds working again.

I'm still looking at the code for a solution, but I can see it is tricky. I just think my points might simplify the matter and find a solution. In the end, I don't think making rss feeds totally inaccessible under securesite is an acceptable tradeoff to solve a very isolated use case.

Thanks for your consideration and hard work on the module.

junyor’s picture

Regarding #1, yes. It makes Secure Site usable with normal caching. Especially in Drupal 6 where caching is used for authenticated users, this is necessary.

Regarding #2, guest access is like anonymous access, but requires a username/password. It allows users without accounts to have anonymous access, which would normally not be available.

Regarding #3, the first drupal_goto is only used if guest access is enabled.

chrisschaub’s picture

Ok, thanks for addressing my points. But, I don't totally agree.

1. Again, I don't see the harm of showing a cached page to a user that just saw it. This is a very isolated use case. If the user clicks on anything in the cached page, it has the same effect as drupal_goto.

2. No, you can easily create a guest user in drupal that behaves like anonymous. I don't see any difference really. And if they have no privs other than access content, why can't many users share a pseudo anon account? An account that does nothing but mimics anon? I don't see the problem.

3. Ok, then why not do this for the one for regular authenticated users? This would solve the problem. RSS feeds are very important, much more important that the problem in #5.

One last thing, this worked for RSS feeds until Sept. 7. Now it's broken. So, this is definitely a bug, and I'm assuming it affects many more users than #5.

junyor’s picture

Regarding #3, the second drupal_goto would still cause it to fail. Getting another user's cached page is a bad thing.

NaX’s picture

I think we solved the Caching problem incorrectly. The browser cache and Drupal cache are two completely different things, but both affect securesite very heavily.

I can’t remember what the Drupal cache testing revealed, but if I remember correctly this is browser caching problem.

I did some searching and I think we need to look at setting some headers.

This page http://www.mnot.net/cache_docs/ goes into a lot of detail about cache control using headers. It also describes some of the problems.

If you also look at http://www.php.net/header you will see a lot of other people have also had problems with preventing caching.

After a very quick look over those two pages, I think we should try and test setting some headers without the goto and see if that resolves the caching problem.

I am not 100% sure what the best headers combination would be, but I think something like this is worth a shot.

drupal_set_header('Cache-Control: public, no-cache');
$ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time()) . " GMT";
drupal_set_header($ExpStr);
return;

Here is also something worth looking into.
http://www.php.net/manual/en/function.session-cache-limiter.php

junyor’s picture

@NaX: I'm pretty sure it's a Drupal caching problem, not a browser caching problem. Otherwise, the issue would not have appeared when running unit tests as the SimpleTest framework does not cache pages.

darren oh’s picture

junyor’s picture

Status: Active » Needs review
StatusFileSize
new984 bytes

@lutegrass: Does the attached patch work-around the problem?

chrisschaub’s picture

Yep, it works, a good interim solution, thanks! I only tested on Drupal 5, but I'm sure it will work on 6 since the code is basically the same.

I was trying to find another way, and had a question. Is the cached page that is incorrectly returned from another "guest" user? Not a real drupal user? Just wondering. I to am wondering if it's a header issue, drupal sets some at login to prevent caching etc. Also, would a well placed "cache_clear_al()" in place of the drupal_goto work?

Thanks.

junyor’s picture

Yes, the returned page is from the "guest" AKA anonymous user. I believe I tried cache_clear_all(), but I don't remember if it worked. But using that would reduce the performance of the cache.

chrisschaub’s picture

Yeah, thought so. I saw this was a past approach that was removed from securesite.

So, if it's an anon user, isn't see another user's page cache expected? I mean, caching one anon user's page and serving for others is the definition of caching, especially for anon? I'm just wondering how serving an "anon realm" page, nothing protected, to a user would compromise any other user's information. They're both anon. Isn't this how Drupal's page cache works anyway? It's not a page cache for each user is it? I've always avoided Drupal cache due to bugs with modules, so sorry for being ignorant on this issue.

junyor’s picture

A logged in user is seeing an anonymous user's cached page instead of their authenticated page.

NaX’s picture

I would like to bring your attention back to my headers theory I had earlier. I also believe this is a drupal cache problem but I also think they both are related.

If you look in bootstrap.inc.
http://api.drupal.org/api/file/includes/bootstrap.inc/5/source

You will find 2 functions.

drupal_page_header()
http://api.drupal.org/api/function/drupal_page_header/5

drupal_page_cache_header($cache)
http://api.drupal.org/api/function/drupal_page_cache_header/5

These function set a lot of headers depending on the circumstances. This would suggest to me that headers could play a role here. I just can’t see a way around drupal setting these headers.

Does anybody know how to override headers that have already been set? What would happen if you had to set a header that has already been set, witch header will the browser listen to. If it is the first then we can try to sent some no caching headers as per my above suggestion, if the browser only accepts the last header sent then we might need to look at implementing hook_exit().

chrisschaub’s picture

The only way I know of is to buffer the output and then overrwrite.

ob_start()
some headers are set with header()
ob_end_flush() ... the headers get sent out.

You'd have to call ob_start() and catch drupal's headers before they are sent to the browser. My understanding is that calling header automatically sends the data to the browser. At that point, I'm guessing all bets are off. It could be very browser dependent at that point.

darren oh’s picture

Browsers accept the last header sent, with some exceptions in the case of the WWW-Authenticate header. The correct behavior for the WWW-Authenticate header is to use the header with the strongest authentication method the browser is capable of, but some browsers use the first WWW-Authenticate header encountered and some use the last.

junyor’s picture

I don't think changing the headers sent to browsers will help here. Like I already said, the problem occurs in unit tests, which don't support caching. The problem is with Drupal's cache, not browser caches.

darren oh’s picture

I'm not sure what causes the caching problem in the Drupal 5 version, but HEAD only requires a redirect from the logout page to prevent this problem. The problem occurs when Secure Site is set to accept any guest user name and password and caching is enabled.

Fixed HEAD in CVS commit 149822.

darren oh’s picture

Status: Needs review » Reviewed & tested by the community

The 5.x version doesn't need a proper fix unless someone has plans to continue developing it. I suggest we just make it work. Junyor?

junyor’s picture

I guess I don't mind. We have other cache work-arounds, so an additional well-documented one isn't that much of a problem.

darren oh’s picture

Status: Reviewed & tested by the community » Fixed

Fixed in CVS commit 149846.

Anonymous’s picture

Status: Fixed » Closed (fixed)

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

jvinci’s picture

Seems to work on my system. When will this patch be rolled into the next version of SecureSite?

  • Commit 8f5a768 on 6.x-2.x, 7.x-2.x, master, 8.x-1.x by Darren Oh:
    #323470 by Darren Oh: Fixed HTTP authentication for feed readers.