Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

What Voodoo is behind 4184? (Website Development)


Recommended Posts

For some reason when osCommerce/OM/Custom/Site/Website/Template/Amy/Content/main.html is equal to or more than 4184 bytes, a "PHP Warning: Cannot modify header information - headers already sent by" is given when a redirect occurs.

 

This can be seen by going to this page:

 

http://www.oscommerce.com/_&Blahblahblah

 

it doesn't exist and it should redirect back to the front page. It doesn't though because main.html is over 4184 bytes.

 

Hmmmmmm!

:heart:, osCommerce

Link to comment
Share on other sites

Yeah that's exactly what I mean. If the main template file stays below 4184 bytes then a redirect occurs. As it is currently over that size, headers are being sent somewhere in preg_replace_callback() which blocks the redirect occurring (thus the blank content page you're now seeing).

 

I will have to debug this over the weekend :)

:heart:, osCommerce

Link to comment
Share on other sites

I just fed the page to the W3C validator, and it reported 147 errors! The chief offender seems to be that "logo" in the comment with the long runs of "--" that it thinks is an attempt to end the comment. Maybe remove that comment so it validates, and try again? Although the page HTML looked reasonable otherwise, who knows?

Link to comment
Share on other sites

The issue seems really to appear for character combination "_&" (like @@wHiTeHaT said)

 

http://www.oscommerce.com/_&kuku = no redirect

http://www.oscommerce.com/&kuku = redirect ok

http://www.oscommerce.com/_kuku = redirect ok

 

Maybe it has something to do with the string examination?

Link to comment
Share on other sites

The _ is actually an Application Controller class that handles a couple of pages (Community Sponsorships, Personal not business, ..). It's a valid PHP class name (class _ {}) so that is not the cause of the error. It's something in the template parsing logic that stops parsing, sends headers, and continues parsing again.

 

It's not output buffering either as it is not active parsing the template pages.

 

Still investigating! :)

:heart:, osCommerce

Link to comment
Share on other sites

The magic number is not 4184 but 4096 - this is the default value PHP uses for output buffering.

 

Here is what is happening:

 

1. On index.php there is:

 

echo $OSCOM_Template->getContent();

 

2. During getContent(), the Site, Application, and any Actions are initialized to return the page content. Here a redirect is called in a controller destructor before any content is echoed. This works as when no content is echoed, no headers are sent.

 

3. Let's change that echo statement to:

 

$blah = $OSCOM_Template->getContent();
echo $blah;

 

4. If $blah is <= 4095 bytes, the redirect occurs without a problem. If it is >= 4096, $blah is echoed out before the controller destructor is called thus the "headers already sent" error when it tries to do the redirect.

 

This can be confirmed by doing the following:

 

// REDIRECT IS SUCCESSFUL:
$blah = $OSCOM_Template->getContent();
$blah = substr($blah, 0, 4095);
echo $blah;

 

// REDIRECT FAILS:
$blah = $OSCOM_Template->getContent();
$blah = substr($blah, 0, 4096);
echo $blah;

 

Some voodoo magic in PHP's memory management routine.

 

We can get around this by using output buffering, that's something I want to avoid though.

 

Investigating further....

:heart:, osCommerce

Link to comment
Share on other sites

tldr; output_buffering affects the internal PHP buffering and is not specific to ob_start().

 

That voodoo magic is due to PHP's internal output buffering - as soon as an echo statement is >= 4096 bytes, PHP sends this part to the client before the next part of the echo statement is sent. (PHP has an internal buffer even if ob_start() is not used)

 

The problem above could be fixed by increasing the default output_buffering value from 4096 to a higher value.

 

As this was a specific problem not related to the framework, I updated the _ controller class to handle the redirect differently.

 

Here is what happens for all Application controller classes:

 

1. initialize() is run to initialize the default application template page (the first page of the url, eg /Us loading the Who We Are page)

2. runActions() is run to handle specific application template pages (the second and onwards part of the url, eg /Us&Team loading The Team page). If a valid Action is found, an internal $_current_action variable is set with the name of the Action being called.

 

As the _ Application has no default page I wanted it to redirect to the index page and also do the redirect for Actions that didn't exist (eg, /_&Blahblahblah).

 

It wasn't possible to do the redirect in initialize() as the runActions() method wasn't called yet (and the $_current_action variable remaining empty). That's why I first tried to do the redirect in the class destructor which worked until additional lines were added to the base template file growing pass the 4096 bytes size.

 

I thought about adding a 3rd function call to handle situations after runActions() but didn't like the idea just for this single scenario. It was going to be called afterParty() so perhaps we'll see that in the future ;) What's being done now is the _ Application controller class is overriding the runActions() method and doing the redirect there if $_current_action is empty.

:heart:, osCommerce

Link to comment
Share on other sites

I just fed the page to the W3C validator, and it reported 147 errors! The chief offender seems to be that "logo" in the comment with the long runs of "--" that it thinks is an attempt to end the comment. Maybe remove that comment so it validates, and try again? Although the page HTML looked reasonable otherwise, who knows?

 

Just fixed that with the logo - thanks for pointing this out! I didn't know it was illegal to have -- in a html comment.

 

The remaining errors will also soon be fixed.

:heart:, osCommerce

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...