HTTP.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package de.tudarmstadt.informatik.hostage.protocol;
  2. import java.security.SecureRandom;
  3. import java.text.SimpleDateFormat;
  4. import java.util.ArrayList;
  5. import java.util.Calendar;
  6. import java.util.List;
  7. import java.util.Locale;
  8. import java.util.TimeZone;
  9. import android.content.Context;
  10. import de.tudarmstadt.informatik.hostage.Hostage;
  11. import de.tudarmstadt.informatik.hostage.R;
  12. import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
  13. import de.tudarmstadt.informatik.hostage.wrapper.Packet;
  14. /**
  15. * HTTP protocol. Implementation of RFC document 1945. It can handle the
  16. * following requests: GET, HEAD, TRACE, POST, DELETE. For all other requests
  17. * '400 Bad Request' will be replied.
  18. *
  19. * @author Wulf Pfeiffer
  20. */
  21. public class HTTP implements Protocol {
  22. /**
  23. * Get the current time in html header format.
  24. *
  25. * @return the formatted server time.
  26. */
  27. private String getServerTime() {
  28. Calendar calendar = Calendar.getInstance();
  29. SimpleDateFormat dateFormat = new SimpleDateFormat(
  30. "EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
  31. dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
  32. return dateFormat.format(calendar.getTime());
  33. }
  34. /** Whole request that was sent by the client */
  35. private String request = "";
  36. // version stuff
  37. private String[][][] possibleHttpVersions = {
  38. {
  39. { "Apache/2.0." },
  40. { "28", "32", "35", "36", "39", "40", "42", "43", "44",
  41. "45", "46", "47", "48", "49", "50", "51", "52",
  42. "53", "54", "55", "58", "59", "61", "63", "64",
  43. "65" } },
  44. {
  45. { "Apache/2.2." },
  46. { "0", "2", "3", "4", "6", "8", "9", "10", "11", "12",
  47. "13", "14", "15", "16", "17", "18", "19", "20",
  48. "21", "22", "23", "24", "25" } },
  49. { { "Apache/2.3." },
  50. { "4", "5", "6", "8", "10", "11", "12", "14", "15", "16" } },
  51. { { "Apache/2.4." }, { "1", "2", "3", "4", "6" } },
  52. { { "Microsoft-IIS/" }, { "5.1", "7.0", "8.0" } } };
  53. private String serverVersion = initServerVersion();
  54. private String initServerVersion() {
  55. SecureRandom rndm = new SecureRandom();
  56. int majorVersion = rndm.nextInt(possibleHttpVersions.length);
  57. String version;
  58. String sharedPreferencePath = Hostage.getContext().getString(
  59. R.string.shared_preference_path);
  60. String profile = Hostage
  61. .getContext()
  62. .getSharedPreferences(sharedPreferencePath,
  63. Context.MODE_PRIVATE).getString("os", "");
  64. System.out.println(profile);
  65. if (profile.equals("Windows 7") || profile.equals("Windows Server 2008")) {
  66. version = "Microsoft-IIS/7.5";
  67. } else if (profile.equals("Windows Server 2012") || profile.equals("Windows 8")) {
  68. version = "Microsoft-IIS/8.0";
  69. } else if (profile.equals("Windows XP")) {
  70. version = "Microsoft-IIS/5.1";
  71. } else {
  72. version = possibleHttpVersions[majorVersion][0][0]
  73. + possibleHttpVersions[majorVersion][1][rndm
  74. .nextInt(possibleHttpVersions[majorVersion][1].length)];
  75. }
  76. return version;
  77. }
  78. private String httpVersion = "HTTP/1.1";
  79. private static String htmlDocumentContent = HelperUtils.getRandomString(32, false);
  80. // request codes
  81. private static final String OPTIONS = "OPTIONS";
  82. private static final String GET = "GET";
  83. private static final String HEAD = "HEAD";
  84. private static final String POST = "POST";
  85. private static final String PUT = "PUT";
  86. private static final String DELETE = "DELETE";
  87. private static final String TRACE = "TRACE";
  88. private static final String CONNECT = "CONNECT";
  89. private static final String STATUS_CODE_200 = "200 OK\r\n";
  90. private static final String STATUS_CODE_400 = "400 Bad Request\r\n";
  91. private static final String STATUS_CODE_505 = "505 HTTP Version not supported\r\n";
  92. /**
  93. * Sets the html document content for HTTP and HTTPS.
  94. *
  95. * @param htmlDocumentContent
  96. */
  97. public static void setHtmlDocumentContent(String htmlDocumentContent) {
  98. HTTP.htmlDocumentContent = htmlDocumentContent;
  99. }
  100. // html header pre and suffix
  101. private String headerPrefix = "Date: " + getServerTime() + "\r\n"
  102. + "Server: " + serverVersion + " \r\n"
  103. + "Vary: Accept-Encoding\r\n" + "Content-Length: ";
  104. private String headerSuffix = "\r\n" + "Keep-Alive: timeout=5, max=100\r\n"
  105. + "Connection: Keep-Alive\r\n" + "Content-Type: text/html\r\n"
  106. + "\r\n";
  107. // html website
  108. private String htmlDocument = "<!doctype html>\n" + "<html lang=\"en\">\n"
  109. + "<head>\n" + "<meta charset=\"UTF-8\">\n" + "<title>"
  110. + htmlDocumentContent + "</title>\n" + "<body>"
  111. + htmlDocumentContent + "</body>\n" + "</head>\n" + "</html>";
  112. // html error pre and suffix
  113. private String errorHtmlPrefix = "<!doctype html>\n"
  114. + "<html lang=\"en\">\n" + "<head>\n"
  115. + "<meta charset=\"UTF-8\">\n" + "<title>";
  116. private String errorHtmlSuffix = "</title>\n" + "</head>\n" + "</html>";
  117. @Override
  118. public int getPort() {
  119. return 80;
  120. }
  121. @Override
  122. public boolean isClosed() {
  123. return true;
  124. }
  125. @Override
  126. public boolean isSecure() {
  127. return false;
  128. }
  129. @Override
  130. public List<Packet> processMessage(Packet requestPacket) {
  131. String request = null;
  132. if (requestPacket != null) {
  133. request = requestPacket.toString();
  134. }
  135. List<Packet> responsePackets = new ArrayList<Packet>();
  136. this.request = request;
  137. if (!request.contains(httpVersion)) {
  138. responsePackets.add(buildPacket(STATUS_CODE_505, ""));
  139. } else if (request.contains(GET)) {
  140. responsePackets.add(buildPacket(STATUS_CODE_200, GET));
  141. } else if (request.contains(HEAD)) {
  142. responsePackets.add(buildPacket(STATUS_CODE_200, HEAD));
  143. } else if (request.contains(TRACE)) {
  144. responsePackets.add(buildPacket(STATUS_CODE_200, TRACE));
  145. } else if (request.contains(OPTIONS)) {
  146. responsePackets.add(buildPacket(STATUS_CODE_400, OPTIONS));
  147. } else if (request.contains(POST)) {
  148. responsePackets.add(buildPacket(STATUS_CODE_200, POST));
  149. } else if (request.contains(PUT)) {
  150. responsePackets.add(buildPacket(STATUS_CODE_400, PUT));
  151. } else if (request.contains(DELETE)) {
  152. responsePackets.add(buildPacket(STATUS_CODE_200, DELETE));
  153. } else if (request.contains(CONNECT)) {
  154. responsePackets.add(buildPacket(STATUS_CODE_400, CONNECT));
  155. } else {
  156. responsePackets.add(buildPacket(STATUS_CODE_400, ""));
  157. }
  158. return responsePackets;
  159. }
  160. @Override
  161. public String toString() {
  162. return "HTTP";
  163. }
  164. @Override
  165. public TALK_FIRST whoTalksFirst() {
  166. return TALK_FIRST.CLIENT;
  167. }
  168. /**
  169. * Builds a html response that can be sent
  170. *
  171. * @param code
  172. * response code that was determined
  173. * @param type
  174. * request type that was sent by the client
  175. * @return the html response
  176. */
  177. private Packet buildPacket(String code, String type) {
  178. String document = "";
  179. if (type.equals(GET)) {
  180. document = htmlDocument;
  181. } else if (type.equals(HEAD) || type.equals(DELETE)) {
  182. document = "";
  183. } else if (type.equals(TRACE)) {
  184. document = request;
  185. } else {
  186. document = errorHtmlPrefix + " " + code + errorHtmlSuffix;
  187. }
  188. return new Packet(httpVersion + " " + code + headerPrefix
  189. + document.length() + headerSuffix + document);
  190. }
  191. }