httpParse.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. define("dojox/io/httpParse", ["dojo/_base/kernel"], function(dojo){
  2. dojo.getObject("io.httpParse", true, dojox);
  3. dojox.io.httpParse = function(/*String*/httpStream, /*String?*/topHeaders,/*Boolean?*/ partial){
  4. // summary:
  5. // Parses an HTTP stream for a message.
  6. // httpStream:
  7. // HTTP stream to parse
  8. // topHeaders:
  9. // Extra header information to add to each HTTP request (kind of HTTP inheritance)
  10. // partial:
  11. // A true value indicates that the stream may not be finished, it may end arbitrarily in mid stream.
  12. // The last XHR object will have a special property _lastIndex that indicates the how far along
  13. // the httpStream could be successfully parsed into HTTP messages.
  14. // return:
  15. // Returns an array of XHR-like object for reading the headers for each message
  16. //
  17. var xhrs=[];
  18. var streamLength = httpStream.length;
  19. do{
  20. var headers = {};
  21. var httpParts = httpStream.match(/(\n*[^\n]+)/);
  22. if(!httpParts){
  23. return null;
  24. }
  25. httpStream = httpStream.substring(httpParts[0].length+1);
  26. httpParts = httpParts[1];
  27. var headerParts = httpStream.match(/([^\n]+\n)*/)[0];
  28. httpStream = httpStream.substring(headerParts.length);
  29. var headerFollowingChar = httpStream.substring(0,1);
  30. httpStream = httpStream.substring(1);
  31. headerParts = (topHeaders || "") + headerParts;
  32. var headerStr = headerParts;
  33. headerParts = headerParts.match(/[^:\n]+:[^\n]+\n/g); // parse the containing and contained response headers with the contained taking precedence (by going last)
  34. for(var j = 0; j < headerParts.length; j++){
  35. var colonIndex = headerParts[j].indexOf(':');
  36. headers[headerParts[j].substring(0,colonIndex)] = headerParts[j].substring(colonIndex+1).replace(/(^[ \r\n]*)|([ \r\n]*)$/g,''); // trim
  37. }
  38. httpParts = httpParts.split(' ');
  39. var xhr = { // make it look like an xhr object, at least for the response part of the API
  40. status : parseInt(httpParts[1],10),
  41. statusText : httpParts[2],
  42. readyState : 3, // leave it at 3 until we get a full body
  43. getAllResponseHeaders : function(){
  44. return headerStr;
  45. },
  46. getResponseHeader : function(name){
  47. return headers[name];
  48. }
  49. };
  50. var contentLength = headers['Content-Length'];
  51. var content;
  52. if(contentLength){
  53. if(contentLength <= httpStream.length){
  54. content = httpStream.substring(0,contentLength);
  55. }else{
  56. return xhrs; // the content is not finished
  57. }
  58. }else if((content = httpStream.match(/(.*)HTTP\/\d\.\d \d\d\d[\w\s]*\n/))){ // assign content
  59. // if we spot another HTTP message coming up, we will just assign all the in between text to the content
  60. content = content[0];
  61. }else if(!partial || headerFollowingChar == '\n'){
  62. // if we have to finish
  63. content = httpStream;
  64. }else{
  65. return xhrs;
  66. }
  67. xhrs.push(xhr); // add it to the list, since it is a full HTTP message
  68. httpStream = httpStream.substring(content.length); // move along the stream
  69. xhr.responseText = content;
  70. xhr.readyState = 4;
  71. xhr._lastIndex = streamLength - httpStream.length; // need to pick up from where we left on streaming connections
  72. }while(httpStream);
  73. return xhrs;
  74. };
  75. return dojox.io.httpParse;
  76. });