Help needed to fix an HTPP Content_Length mismatch problem
MJHanagan
Posts: 189
in Propeller 1
I am playing with the W5200 for QuickStart and encountering an HTTP timeout error when serving htm files. I am using the RenderFile routine included in the W5200_Driver_Demo_1_3_1 collection.
This routine opens the requested file on the SD card and gets its size in bytes. It then creates an HTTP header with a "Content_Length=xxx" header where "xxx" is the number of bytes in the file to be sent. However, this routine searches through the contents of any "htm" file and replaces any occurrence of <!--PROPVARxx-->" with some alternate text which usually contains more or fewer bytes. In the end the total number of byte that gets sent out does not match the value specified in the HTTP Content_Length= header. The result is generally timeout error in the viewing internet browser. This is almost always the case when viewing on my iPhone using Safari or Chrome. It always results in a timeout error when the iPhone is on a WiFi network. Sometimes when the iPhone is on cellular data (not WiFi) the page will render properly when the byte count if only off by a few bytes (cellular connections more tolerant of lost bytes?). Non-htm files render just fine and htm files with no text replacements render fine too since the byte counts in the HTTP header match the bytes sent.
My current workaround is to first run any htm file through the routine and count up the actual number of bytes to be sent. It then creates the HTTP header with the actual count then runs through the procedure a second time to send the contents out via the W5200. This is a bit cumbersome so I wonder if there is a better way to get the file sent with only one pass through the rendering code. Is there a way to avoid the byte count mismatch error and still obey HTTP header rules?
This routine opens the requested file on the SD card and gets its size in bytes. It then creates an HTTP header with a "Content_Length=xxx" header where "xxx" is the number of bytes in the file to be sent. However, this routine searches through the contents of any "htm" file and replaces any occurrence of <!--PROPVARxx-->" with some alternate text which usually contains more or fewer bytes. In the end the total number of byte that gets sent out does not match the value specified in the HTTP Content_Length= header. The result is generally timeout error in the viewing internet browser. This is almost always the case when viewing on my iPhone using Safari or Chrome. It always results in a timeout error when the iPhone is on a WiFi network. Sometimes when the iPhone is on cellular data (not WiFi) the page will render properly when the byte count if only off by a few bytes (cellular connections more tolerant of lost bytes?). Non-htm files render just fine and htm files with no text replacements render fine too since the byte counts in the HTTP header match the bytes sent.
My current workaround is to first run any htm file through the routine and count up the actual number of bytes to be sent. It then creates the HTTP header with the actual count then runs through the procedure a second time to send the contents out via the W5200. This is a bit cumbersome so I wonder if there is a better way to get the file sent with only one pass through the rendering code. Is there a way to avoid the byte count mismatch error and still obey HTTP header rules?
Comments
As far as I can tell it is not compulsory to have one.
The server can simple indicate the content length by closing the connection after sending everything.
Or at least that is what I'm understanding from section 4.4 paragraph 5 of RFC 2616
See here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4
Never tried it myself so I have no idea what happens in practice.
Yes, you can exclude the Content_Length in the HTTP header and it will render the file OK. I was trying to respect the SHOULD include rules of HTTP. I assume the requesting browser wants to know that all data has been received as planned. This would allow the browser to detect any Tx/Rx errors and report something is amiss.
In HTTP 1.0 every request opens a connection, waits for request, sends the response and closes the connection to end the response.
In HTTP 1.1 you CAN send a header to keep the connection open and send multiple request/responses before closing the connection.
If you want to do that you need to send a correct Content_Length.
So double parsing it is. Or Http 1.0.
Enjoy!
Mike
Surely the thing that parses the HTML and does template substitution can count the number of characters it outputs.