myWallJSON
myWallJSON

Reputation: 9502

What is wrong with my redirect machanism?

So I try to create a C++ web server with services and stuff. It is alive here, this is how to compile in in 3 lines under regular user on Linux, and here is it svn.

To redirect users I use such function:

void http_utils::send_found_302( std::string redirect_lication, boost::shared_ptr<boost::asio::ip::tcp::socket> socket, boost::shared_ptr<http_response> response )
{
    response->status = 302;
    response->description = "Found";
    response->headers.insert(std::pair<std::string, std::string>("Location", redirect_lication));
    response->send(*socket);
}

And in Chrome and Safary and IE. I can register and log in into my server. But FF... FF allows me to registe user in DB (meaning sends correct request), but when server trys to redirect it to page I want it shows me sad page=(

So example with pictures: we input credantials: enter image description here

We hit on submit... and is gets stuck on connection for ever...: enter image description here

When we try just to use that URL it tries to go to we see that it got part of "Found response" but has not redirected itself...( If we would try to login with chrome we would get all correct, also if we would just follow that url in chrome we would get redirected to where needed and see such image: enter image description here

I created a simple user: [email protected] with pass 123456 so you can try it out...

So what is wrong with the way I redirect? what shall be added to response to make it work for FF?


At the end of the day I made this:

   void http_utils::send_found_302( const std::string & redirect_lication, boost::shared_ptr<boost::asio::ip::tcp::socket> socket, boost::shared_ptr<http_response> response )
    {
            /* if there was no Fire Fox and probably other dull browsers we would do this (Chrome, IE, Safari tested):
             *
             *\code
                    response->status = 302;
                    response->description = "Found";
                    response->headers.insert(std::pair<std::string, std::string>("Location", redirect_lication));
                    response->send(*socket);
             * \endcode
             *
             * but indeed there are.
             *
             * We could also create simple HTML redirection page - would work anywhere.
             * \code
            std::ostringstream data_stream;
            data_stream << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head><script type=\"text/javascript\">location.replace(\"" 
                    << redirect_lication << "\");</script><noscript><meta http-equiv=\"refresh\" content=\"0; url= "
                    << redirect_lication << "\"></noscript></head><body><p>Please turn on JavaScript!</p><a href=\"" 
                    << redirect_lication << "\"><h1>Content awaits you here.</h1></a></body></html>";
            response->headers.insert(std::pair<std::string, std::string>("Cache-Control", "max-age=0"));
            response->headers.insert(std::pair<std::string, std::string>("Pragma", "no-cache"));
            http_utils::send(data_stream.str(), socket, response);
             * \endcode
             * 
             * so we decided to mix - html page and HTTP redirection
             */

            response->description = "Found";
            response->headers.insert(std::pair<std::string, std::string>("Location", redirect_lication));
            response->headers.insert(std::pair<std::string, std::string>("Content-Location", redirect_lication));
            response->headers.insert(std::pair<std::string, std::string>("Refresh", std::string("0; url=" + redirect_lication)));
            response->headers.insert(std::pair<std::string, std::string>("Cache-Control", "max-age=0"));
            response->headers.insert(std::pair<std::string, std::string>("Pragma", "no-cache"));
            std::ostringstream data_stream;
            data_stream << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head><script type=\"text/javascript\">location.replace(\"" 
                    << redirect_lication << "\");</script><noscript><meta http-equiv=\"refresh\" content=\"0; url= "
                    << redirect_lication << "\"></noscript></head><body><p>Please turn on JavaScript!</p><a href=\"" 
                    << redirect_lication << "\"><h1>Content awaits you here.</h1></a></body></html>";

            http_utils::send(302, data_stream.str(), socket, response);

    }

Let me explain: Current FF did not like my 302 and 303 redirection... so Simple solution - was to move the battle to the other side - side of HTML so I created simple code that returns HTML page that would auto redirect user or at least present him with correct link. Tested it - all worked as was desired (with short local links). Than I added solution that also worked not only I send HTML page but, also relocation headers. This shall work anywhere, and if browser is smart it shall not load contents of redirection page at all...)

So now all works.=) And thanks to KayEss answer I made all links absolute now... Why not?)

Upvotes: 3

Views: 838

Answers (1)

KayEss
KayEss

Reputation: 2300

For best portability the location header needs to be an absolute URL. It looks like you're trying to send a relative one.

I.e.:

Location: http://example.com/path/image.png

Instead of:

Location: image.png

Upvotes: 1

Related Questions