httpParse.js 3.3 KB

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