prism-http.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. (function (Prism) {
  2. /**
  3. * @param {string} name
  4. * @returns {RegExp}
  5. */
  6. function headerValueOf(name) {
  7. return RegExp('(^(?:' + name + '):[ \t]*(?![ \t]))[^]+', 'i');
  8. }
  9. Prism.languages.http = {
  10. 'request-line': {
  11. pattern: /^(?:CONNECT|DELETE|GET|HEAD|OPTIONS|PATCH|POST|PRI|PUT|SEARCH|TRACE)\s(?:https?:\/\/|\/)\S*\sHTTP\/[\d.]+/m,
  12. inside: {
  13. // HTTP Method
  14. 'method': {
  15. pattern: /^[A-Z]+\b/,
  16. alias: 'property'
  17. },
  18. // Request Target e.g. http://example.com, /path/to/file
  19. 'request-target': {
  20. pattern: /^(\s)(?:https?:\/\/|\/)\S*(?=\s)/,
  21. lookbehind: true,
  22. alias: 'url',
  23. inside: Prism.languages.uri
  24. },
  25. // HTTP Version
  26. 'http-version': {
  27. pattern: /^(\s)HTTP\/[\d.]+/,
  28. lookbehind: true,
  29. alias: 'property'
  30. },
  31. }
  32. },
  33. 'response-status': {
  34. pattern: /^HTTP\/[\d.]+ \d+ .+/m,
  35. inside: {
  36. // HTTP Version
  37. 'http-version': {
  38. pattern: /^HTTP\/[\d.]+/,
  39. alias: 'property'
  40. },
  41. // Status Code
  42. 'status-code': {
  43. pattern: /^(\s)\d+(?=\s)/,
  44. lookbehind: true,
  45. alias: 'number'
  46. },
  47. // Reason Phrase
  48. 'reason-phrase': {
  49. pattern: /^(\s).+/,
  50. lookbehind: true,
  51. alias: 'string'
  52. }
  53. }
  54. },
  55. 'header': {
  56. pattern: /^[\w-]+:.+(?:(?:\r\n?|\n)[ \t].+)*/m,
  57. inside: {
  58. 'header-value': [
  59. {
  60. pattern: headerValueOf(/Content-Security-Policy/.source),
  61. lookbehind: true,
  62. alias: ['csp', 'languages-csp'],
  63. inside: Prism.languages.csp
  64. },
  65. {
  66. pattern: headerValueOf(/Public-Key-Pins(?:-Report-Only)?/.source),
  67. lookbehind: true,
  68. alias: ['hpkp', 'languages-hpkp'],
  69. inside: Prism.languages.hpkp
  70. },
  71. {
  72. pattern: headerValueOf(/Strict-Transport-Security/.source),
  73. lookbehind: true,
  74. alias: ['hsts', 'languages-hsts'],
  75. inside: Prism.languages.hsts
  76. },
  77. {
  78. pattern: headerValueOf(/[^:]+/.source),
  79. lookbehind: true
  80. }
  81. ],
  82. 'header-name': {
  83. pattern: /^[^:]+/,
  84. alias: 'keyword'
  85. },
  86. 'punctuation': /^:/
  87. }
  88. }
  89. };
  90. // Create a mapping of Content-Type headers to language definitions
  91. var langs = Prism.languages;
  92. var httpLanguages = {
  93. 'application/javascript': langs.javascript,
  94. 'application/json': langs.json || langs.javascript,
  95. 'application/xml': langs.xml,
  96. 'text/xml': langs.xml,
  97. 'text/html': langs.html,
  98. 'text/css': langs.css,
  99. 'text/plain': langs.plain
  100. };
  101. // Declare which types can also be suffixes
  102. var suffixTypes = {
  103. 'application/json': true,
  104. 'application/xml': true
  105. };
  106. /**
  107. * Returns a pattern for the given content type which matches it and any type which has it as a suffix.
  108. *
  109. * @param {string} contentType
  110. * @returns {string}
  111. */
  112. function getSuffixPattern(contentType) {
  113. var suffix = contentType.replace(/^[a-z]+\//, '');
  114. var suffixPattern = '\\w+/(?:[\\w.-]+\\+)+' + suffix + '(?![+\\w.-])';
  115. return '(?:' + contentType + '|' + suffixPattern + ')';
  116. }
  117. // Insert each content type parser that has its associated language
  118. // currently loaded.
  119. var options;
  120. for (var contentType in httpLanguages) {
  121. if (httpLanguages[contentType]) {
  122. options = options || {};
  123. var pattern = suffixTypes[contentType] ? getSuffixPattern(contentType) : contentType;
  124. options[contentType.replace(/\//g, '-')] = {
  125. pattern: RegExp(
  126. '(' + /content-type:\s*/.source + pattern + /(?:(?:\r\n?|\n)[\w-].*)*(?:\r(?:\n|(?!\n))|\n)/.source + ')' +
  127. // This is a little interesting:
  128. // The HTTP format spec required 1 empty line before the body to make everything unambiguous.
  129. // However, when writing code by hand (e.g. to display on a website) people can forget about this,
  130. // so we want to be liberal here. We will allow the empty line to be omitted if the first line of
  131. // the body does not start with a [\w-] character (as headers do).
  132. /[^ \t\w-][\s\S]*/.source,
  133. 'i'
  134. ),
  135. lookbehind: true,
  136. inside: httpLanguages[contentType]
  137. };
  138. }
  139. }
  140. if (options) {
  141. Prism.languages.insertBefore('http', 'header', options);
  142. }
  143. }(Prism));