I have a content type in a Drupal 6 site that allows the creator of a node to mark the node as "withdrawn"; he can still see it, but attempts by others to see it are caught and redirected somewhere else, like their user page.

So far so good, but I'm concerned about what happens when search bots show up looking for the node; they get a 302 response from the server and are then redirected to the "somewhere else" page with an http code 200. What ought to happen (I think) is that the request by Googlebot for the node should result in a 403 or 410 error code, causing (eventually) the page to get dropped from the Google index. So I'd like to have the page generation work just like it is, except with a 401/410/whatever getting sent back as the response to the initial request.

I've tried putting some header() calls into the part of the code that detects the disallowed access, but they're not working, presumably because I'm too far along in the page construction by the time that call happens for the new header information to matter.

Is there any way to get this error code generated while still getting the user to the page I want them to be at?

I think I've got an answer for this -- at least, it seems to be working for me, and (after the fact) seems fairly obvious :) After detecting the issue:

Do drupal_set_header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); to generate the 404 response. This works where header() doesn't; it knows how to fit the header into the page being generated.

You can't do a drupal_goto() to generate the desired content -- this will generate a new page with a new URL. Instead, call whatever code gets called at your desired destination page and PRINT (not return) the result.

This gives me what I want: an apparent 404 error at the desired location, but with content corresponding to what I want. This is in some sense a custom 404 page; I played around with the customerror module, but doing it this way seemed simpler. Anyway, it works...