This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

Problem with our Web site

0

Thank you. I have a small Web site that makes a Ajax "GET" request every 200ms to a Web server. The Web site wait for a small document (750 bytes) from the server, it displays the document data before to send a new request to the server. The document is updated periodically every 200ms by another process (priority superior than web server'one). There is no synchronization between two processes. So, the reading task (web server) may be interrupted from time to time by the writing task, but not for long time. The data in the document could be error some times, but it is not a big problem, because the data is only for display, in addition we check data and display only if data is good. The problem is that our application is stopped after some hours of run, and always after reception of a "Continuation or non-HTTP traffic" packet. And the web site doesn't know to detect this case. As the packet "says" the data is not finished, it is keeped to wait some packets more that never arrive, so it is blocked. I think it is an error coming from the server side, but is it possible to fix it in the web site or not ? Case OK from Wireshark (during some hours) :

HTTP/1.1 200 OK (application/octet-stream)

case not OK from Whireshark :

HTTP/1.1 200 OK (application/octet-stream)
Continuation or non-HTTP traffic.

Following is the source code of the web site :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>XPS-Q8 - Test AJAX</title>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1" />
<script type="text/javascript">

var req=null; var timeout=null; function requestGetAJAX() { document.FP_MoveFormRefresh.test2.value = "-1 -1"; timeout=null; var url = "/lnkXpsdata.json?nocache=" + Math.random(); req=createRequest(); req.onreadystatechange=stateChange; req.open("GET", url, true); req.send(null); timeout=setTimeout("treatmentTimeout()", 5000); } function treatmentTimeout() { req.abort(); document.FP_MoveFormRefresh.test.value = "Ajax request timeout"; requestGetAJAX(); } function treatmentDataError() { req.abort(); requestGetAJAX(); } function treatmentDataOK() { req.abort(); requestGetAJAX(); } function createRequest() { var request=null; if (window.XMLHttpRequest) { request=new XMLHttpRequest(); if (request.overrideMimeType) request.overrideMimeType("text/xml"); } else if (window.ActiveXObject) { try { request=new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { request=new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { alert("Browser doesn't support AJAX"); } } } return request; } function stateChange(dataText) { document.FP_MoveFormRefresh.test2.value = req.readyState + " " + req.status; if(req.readyState == 4) { if(req.status == 200) { if(timeout != null) { clearTimeout(timeout); timeout=null; } if(req.getResponseHeader("Content-Length") > 0) { if((req.responseText.indexOf("{\n") >= 0) && (req.responseText.indexOf("]\n}") > 0)) { var contenttype=req.getResponseHeader("Content-Type"); if(contenttype.indexOf("Continuation or non-HTTP traffic") >= 0) { <! This line doesn't work !!!!! /> document.FP_MoveFormRefresh.test.value = "Continu/non-HTTP traffic"; setTimeout("treatmentDataOK()", 2000); } else { document.FP_MoveFormRefresh.test.value = contenttype; parseRequestData(req.responseText); setTimeout("treatmentDataOK()", 200); } } else { document.FP_MoveFormRefresh.test.value = "Ajax data error"; setTimeout("treatmentDataError()", 2000); } } else { document.FP_MoveFormRefresh.test.value = "Ajax data length zero"; setTimeout("treatmentDataError()", 2000); } } else { document.FP_MoveFormRefresh.test.value = "Error status(!=200)=" + req.status; setTimeout("treatmentDataError()", 2000); } } } function parseRequestData(dataText) { var aPos1=null; aPos1=document.getElementById("ajpos1"); var aStat1=null; aStat1=document.getElementById("ajstate1"); var aPos2=null; aPos2=document.getElementById("ajpos2"); var aStat2=null; aStat2=document.getElementById("ajstate2"); var aPos3=null; aPos3=document.getElementById("ajpos3"); var aStat3=null; aStat3=document.getElementById("ajstate3"); var aPos4=null; aPos4=document.getElementById("ajpos4"); var aStat4=null; aStat4=document.getElementById("ajstate4"); var aPos5=null; aPos5=document.getElementById("ajpos5"); var aStat5=null; aStat5=document.getElementById("ajstate5"); var aPos6=null; aPos6=document.getElementById("ajpos6"); var aStat6=null; aStat6=document.getElementById("ajstate6"); var aPos7=null; aPos7=document.getElementById("ajpos7"); var aStat7=null; aStat7=document.getElementById("ajstate7"); var data=null; data=eval("(" + dataText + ")"); if(data != null) { if(aPos1 != null) aPos1.value=data.positioners[0].position; if(aStat1 != null) aStat1.value=data.positioners[0].state; if(aPos2 != null) aPos2.value=data.positioners[1].position; if(aStat2 != null) aStat2.value=data.positioners[1].state; if(aPos3 != null) aPos3.value=data.positioners[2].position; if(aStat3 != null) aStat3.value=data.positioners[2].state; if(aPos4 != null) aPos4.value=data.positioners[3].position; if(aStat4 != null) aStat4.value=data.positioners[3].state; if(aPos5 != null) aPos5.value=data.positioners[4].position; if(aStat5 != null) aStat5.value=data.positioners[4].state; if(aPos6 != null) aPos6.value=data.positioners[5].position; if(aStat6 != null) aStat6.value=data.positioners[5].state; if(aPos7 != null) aPos7.value=data.positioners[6].position; if(aStat7 != null) aStat7.value=data.positioners[6].state; } } </script> </head> <body onload="requestGetAJAX()"> <form action="/cgi-bin/post.cgi" method="post" name="FP_MoveFormRefresh"> <input type="hidden" name="step" value="131" /> <input type="hidden" name="numoption" value="141" /> <input type="hidden" name="cmd" value="0" /> <input type="hidden" name="posStat0" value="0" /> <input type="hidden" name="posStat1" value="0" /> <input type="hidden" name="posStat2" value="0" /> <input type="hidden" name="posStat3" value="0" /> <input type="hidden" name="posStat4" value="0" /> <input type="hidden" name="posStat5" value="0" /> <input type="hidden" name="posStat6" value="0" /> <div id="calqueMoveRefresh"> <h2>TEST AJAX REQUESTS</h2> <table width="50%" border="0" cellspacing="1" cellpadding="0"> <tr> <td><b>Position</b></td> <td><b>State</b></td> </tr> <tr> <td> <input type="text" name="position1" id="ajpos1" size="20" value="0"/> </td> <td> <input type="text" name="state1" id="ajstate1" size="4" value="0"/> </td> </tr> <tr> <td> <input type="text" name="position2" id="ajpos2" size="20" value="0"/> </td> <td> <input type="text" name="state2" id="ajstate2" size="4" value="0"/> </td> </tr> <tr> <td> <input type="text" name="position3" id="ajpos3" size="20" value="0"/> </td> <td> <input type="text" name="state3" id="ajstate3" size="4" value="0"/> </td> </tr> <tr> <td> <input type="text" name="position4" id="ajpos4" size="20" value="0"/> </td> <td> <input type="text" name="state4" id="ajstate4" size="4" value="0"/> </td> </tr> <tr> <td> <input type="text" name="position5" id="ajpos5" size="20" value="0"/> </td> <td> <input type="text" name="state5" id="ajstate5" size="4" value="0"/> </td> </tr> <tr> <td> <input type="text" name="position6" id="ajpos6" size="20" value="0"/> </td> <td> <input type="text" name="state6" id="ajstate6" size="4" value="0"/> </td> </tr> <tr> <td> <input type="text" name="position7" id="ajpos7" size="20" value="0"/> </td> <td> <input type="text" name="state7" id="ajstate7" size="4" value="0"/> </td> </tr> </table> <br /> <table width="50%" border="0" cellspacing="1" cellpadding="0"> <tr> <td> <input type="text" name="test" size="50" maxlength="50" value=""/> </td> </tr> <tr> <td> <input type="text" name="test2" size="50" maxlength="50" value=""/> </td> </tr> </table> <br /> </table> <table width="50%" border="0" cellspacing="1" cellpadding="0"> <tr> <td> <input type="button" name="restart" value="Re-Start" onclick="requestGetAJAX()"/> </td> </tr> </table> </div> </form> </body> </html>

Thank you very much for help. NewportMicro

asked 18 Jan ‘13, 06:41

NewportMicro's gravatar image

NewportMicro
16113
accept rate: 0%

edited 18 Jan ‘13, 10:47

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196

Thank you. It is done. Below is the link :

http://www.cloudshark.org/captures/c4b78426649d

The IP of the Web server target is 192.168.33.242. The IP of the client web site is 192.168.32.109.

Thank you very much for taking a look at it.

(29 Jan ‘13, 03:28) NewportMicro

I converted your “answer” to a comment as that’s how this site works, see the FAQ for more info.

(29 Jan ‘13, 03:37) grahamb ♦


3 Answers:

0

The document is updated periodically every 200ms by another process (priority superior than web server'one). There is no synchronization between two processes.

without knowing any details about your OS (realtime or not), and the file update process, I believe you are running

  • either into a race condition of the two processes
  • or into a bug of the update process

Race condition:

One process opens the file for a write operation and possibly writes some bytes, then the next process (web server) opens the file for reading. This will end up in unpredictable results.

I suggest to redesign the whole process of updating the information in the file. From the information you gave, there should be some synchronization between the update process and the web server process.

Bug of the update process:

Another possible error could be: the update process itself is buggy and writes a bogus file after some time (did you check that?), which would explain why you run into this only after a few hours.

As @SYN-bit said, without a capture file it is hard to analyze. But even with a capture file, you may not see the real reason for the problem, without analyzing the problem on the system itself.

Regards
Kurt

answered 21 Jan '13, 07:34

Kurt%20Knochner's gravatar image

Kurt Knochner ♦
24.8k1039237
accept rate: 15%

edited 21 Jan '13, 07:40

2

I have looked at your tracefile and found the cause of the problem. If you filter with "tcp.stream==1308" you will see that the server responds with a "Content-Length:754" header, while in fact the content is 756 bytes long.

The webserver should respond with the correct content-length. So you have to be aware that the file can get written to between functions. So if your code looks something like this:

len=getLengthOfFile("file");
printf("Content-Length: %d\n", len);
printf("\r\n\r\n");
data=readFile("file");
printf("%s",data);

You might get into this kind of problem (when a new file is being written between the getLengthOfFile() and readFile()).

Also, your client code could be made more robust in handling errors and exceptions.

answered 29 Jan '13, 06:33

SYN-bit's gravatar image

SYN-bit ♦♦
17.1k957245
accept rate: 20%

Great.

Thank you very much for the excellent analyse. I will do as you did and then inform to you the result.

Have a nice day.

(30 Jan '13, 01:10) NewportMicro

0

I can think of a couple of reasons why wireshark displays the HTTP in those two ways. But I'd like to not guess but look at the packets to determine what the cause might be.

Could you please post the wireshark pcap file to www.cloudshark.org and paste the link here in a comment?

(Only if you are not revealing privacy sensitive information in the pcap file)

answered 20 Jan '13, 01:53

SYN-bit's gravatar image

SYN-bit ♦♦
17.1k957245
accept rate: 20%

Thank you for your comments. I tried to upload a pcap file that showing the problem but I don't know how to do. Could you show me how to upload a pcap file to www.cloudshark.org ?

(29 Jan '13, 00:45) NewportMicro

Open 'cloudshark.org' in your browser, click the button (large panel really) with the label "Drag and Drop a capture file to upload" and then a file browser dialog should open which allows you to choose a capture to upload. Post a link back to the uploaded capture file by editing your question, or adding a comment to an existing answer.

(29 Jan '13, 01:40) grahamb ♦