Skip to main content
Topic: Problems with MAX_HTTP_CONNECTIONS > 1 (Read 3577 times) previous topic - next topic

Problems with MAX_HTTP_CONNECTIONS > 1

I've built the code for this project successfully and managed to upload it via the bootloader.
It serves out files fine....but...when the browser has > 1 simultaneous requests, the server tends to corrupt the served files (typically, .js files used in a simple html page end up with garbage appended to the end)
Setting MAX_HTTP_CONNECTIONS back to 1 solves the problem, so seems like a bug in the Microchip HTTP2 stack (is this likely? )

A bit more digging (that is, debugging HTTP2_MDD.c with printf() statements... I have no debugger ), it would seem that in the SM_SERVE_TEXT_DATA: case (around line 1566 ) the value for numBytes isn't being switched to the file being read for the packet to be sent for this time around the service loop; that is, there is one numBytes variable, that isn't being reset when HTTPLoadConn() switches the tcp connection (that's mostly a guess - I haven't proven that this function is called at all, but seems that it should be when > 1 HTTP connection is allowed)

So firstly - is anyone else seeing this problem too?

And I don't know if it's just me, but all of the if..else.. cases in SM_SERVE_TEXT_DATA could be replaced simply with
Code: [Select]
			if(availbleTcpBuffSize != 0){
    //count will be the minimum of databuffer size, available TCP buffer and bytes remaining in file being served
WORD count = mMIN( 64, availbleTcpBuffSize ); //64 = buffer size (TODO: change to const WORD buffer_size = ?? or #define and use in declaration of databuffer )
count = mMIN( count , numBytes );
len=FSfread(databuffer, count, 1, curHTTP.file);
TCPPutArray(sktHTTP, databuffer, count);
numBytes -= count;

This works for me, anyhow. Doesn't solve the suspected bug though.
Does anyone know what the legality of distibuting patches against the Microchip stack is, given that we can't distribute the stack itself in source form?

Anyhow, looking forward to any feedback,

Re: Problems with MAX_HTTP_CONNECTIONS > 1

Reply #1
Awesome!  Using MAX_HTTP_CONNECTIONS = 1 instead of the default value of 2 fixes the problem I described in ... opic=373.0

Would be interesting, where the bug is.

Re: Problems with MAX_HTTP_CONNECTIONS > 1

Reply #2
Mind you, the EEPROM server works fine with the default setting of 2, so the problem might be specific to the MDD library?

Re: Problems with MAX_HTTP_CONNECTIONS > 1

Reply #3
Thanks Markus,

As you're also seeing a problem, I think it's safe to say there is a bug here.

The HTTPSendFile() function is split into two sections: the #ifdef STACK_USE_MDD part and the #else section that uses MPFSGetArray() to get the files to serve.
The latter section ( the EEPROM specfic part ) is much simpler than the MDD section; looking at it, it doesn't seem to have the same bug, so I definately think it's in HTTPSendFile(), not the MDD library.

I'll see what I can do with it.

Re: Problems with MAX_HTTP_CONNECTIONS > 1

Reply #4
After some digging I've managed to get it to serve more than 1 static file concurrently, but dynamic variables and includes are still broken.
The problem seems to be that the STACK_USE_MDD sections in HTTP2_MDD were not written to expect more than 1 http connection at a time; there's lots of static variables in HTTPSendFile() that shouldn't be static; they are state that need to be saved and restored in the HTTP_CONN struct for each connection.

It could be fixed, but using MAX_HTTP_CONNECTIONS = 1 is a simpler workaround. I'm not sure if there's any real downside to only serving one file at a time anyway?

Given that we would all be better off with a truly open source software stack, the effort is probably better invested in porting or implementing a new webserver on top of the uIP port.


Re: Problems with MAX_HTTP_CONNECTIONS > 1

Reply #5
* The MDD server seems to be quite slow compared to the EEPROM server.  When clicking around on the Microchip demo web site using the EEPROM server, the new pages appear almost instantaneously.  When serving the pages from the SD card using the MDD server, it takes about one second until the new page appears.  Ping times also are quite different: <1ms using the EEPROM server, and about 30ms average using the MDD server.  I recompiled the EEPROM server also using MAX_HTTP_CONNECTIONS 1, to rule out any differences related to that.  I was not able to see any difference whether using 1 or 2 MAX_HTTP_CONNECTIONS.

* Although the MDD server seems to work better when using MAX_HTTP_CONNECTIONS 1, it is nevertheless somehow fishy: When quickly reloading a page (Ctrl+R or clicking multiple times at the browsers Reload button), the page contents is messed up.  IMO the MDD server is just what it says it is: C:Microchip SolutionsMicrochipHelpRunning the TCPIP MDD Demo App (Beta Release).pdf -> *Beta*

Re: Problems with MAX_HTTP_CONNECTIONS > 1

Reply #6
I have benchmarked both the EEPROM sserver and the SD card server (full results attached). Each was configured for a max of 2 concurrent connections.

Unsurprisingly, the very much simpler EEPROM server is significantly faster - successfully serving the /dyndns/index.html file (and its included files) 25.62 times per second for a transfer rate of 67.97 kB/s compared with the SD card server's 1.55 times per second and 4.01 kB/s.

As expected, the EEPROM server was also ~25% faster when asked to serve four concurrent requests, compared with one no doubt due to the fact that it has two sockets to play with as opposed to one. In fact, the SD card server showed no significant difference when asked to serve four concurrent requests compared with one.

What was unexpected (though I had suspected it from what I'd been observing) was that the SD card server did not corrupt any of the pages even when asked to serve four concurrent requests. From digging around in the SD card server code, and logging requests to its telnet server, it looks to me that what the SD card server cannot handle is reset/partial connections exercised by hitting Reload in the web browser in quick succession.

Unlike Markus, my ping times for both servers are not significantly different: average 0.989ms (EEPROM) vs 1.001 (SD Card).