DumpHttpRequest.dart
/* Dart code sample : Simple tool for HTTP server development Returns contents of the HTTP request to the client 1. Save these files into a folder named DumpHttpRequest. 2. From Dart editor, File > Open Folder and select this DumpHttpRequest folder. 3. Run DumpHttpRequest.dart as server. 4. Access the DumpHttpRequest.html file from your browser such as : file:///C:/ c /DumpHttpRequest/DumpHttpRequest.html 5. Enter some text to the text areas and click gSubmit using POSTh or gSubmit using GETh button. 6. This server will return available data from the request. This data is also available on the Dart editorfs console. Ref: www.cresc.co.jp/tech/java/Google_Dart/DartLanguageGuide.pdf (in Japanese) May 2012, by Cresc Corp. June 2012 (revised to incorporate new APIs) */ #import("dart:io"); #import("dart:utf", prefix:"utf"); final HOST = "127.0.0.1"; final PORT = 8080; final LOG_REQUESTS = true; void main() { HttpServer server = new HttpServer(); server.addRequestHandler((HttpRequest req){return (req.path == '/DumpHttpRequest');} , requestReceivedHandler); server.listen(HOST, PORT); print("Serving the dump out on http://${HOST}:${PORT}."); } void requestReceivedHandler(HttpRequest request, HttpResponse response) { String bodyString = ""; // request body byte data var completer = new Completer(); if (request.method == "GET") completer.complete("query string data received"); else if (request.method == "POST") { var strins = new StringInputStream(request.inputStream, Encoding.UTF_8); strins.onData = (){ bodyString = bodyString.concat(strins.read()); }; strins.onClosed = () { completer.complete("body data received"); }; strins.onError = (Exception e) { print('exeption occured : ${e.toString()}'); }; } else { response.statusCode = HttpStatus.METHOD_NOT_ALLOWED; response.outputStream.close(); return; } // process the request and send a response completer.future.then((data){ if (LOG_REQUESTS) { print(createLogMessage(request, bodyString)); } response.headers.add("Content-Type", "text/html; charset=UTF-8"); response.outputStream.writeString(createHtmlResponse(request, bodyString)); response.outputStream.close(); }); } // create html response text String createHtmlResponse(HttpRequest request, String bodyString) { var res = '''<html> <head> <title>DumpHttpRequest</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body> <H1>Data available from the request</H1> <pre>${makeSafe(createLogMessage(request, bodyString)).toString()} </pre> </body> </html> '''; return res; } // create log message StringBuffer createLogMessage(HttpRequest request, [String bodyString]) { var sb = new StringBuffer( '''request.method : ${request.method} request.path : ${request.path} request.uri : ${request.uri} request.queryString : ${request.queryString} request.queryParameters : '''); request.queryParameters.forEach((key, value){ sb.add(" ${key} : ${value}\n"); }); sb.add('''request.cookies : '''); request.cookies.forEach((value){ sb.add(" ${value.toString()}\n"); }); sb.add('''request.headers.expires : ${request.headers.expires} request.headers.host : ${request.headers.host} request.headers.port : ${request.headers.port} request.headers : '''); var str = request.headers.toString(); for (int i = 0; i < str.length - 1; i++){ if (str[i] == "\n") sb.add("\n "); else sb.add(str[i]); } if (request.method == "POST") { var enctype = request.headers["content-type"]; if (enctype[0].contains("text")) sb.add("\nrequest body string :\n ${bodyString.replaceAll('+', ' ')}"); else if (enctype[0].contains("urlencoded")) sb.add("\nrequest body string (URL decoded):\n ${urlDecode(bodyString)}"); } return sb.add("\n"); } // make safe string buffer data as HTML text StringBuffer makeSafe(StringBuffer b) { var s = b.toString(); b.clear(); b = new StringBuffer(); for (int i = 0; i < s.length; i++){ if (s[i] == '&') b.add('&'); else if (s[i] == '"') b.add('"'); else if (s[i] == "'") b.add('''); else if (s[i] == '<') b.add('<'); else if (s[i] == '>') b.add('>'); else b.add(s[i]); } return b; } // URL decoder decodes url encoded utf-8 bytes // Use this method to decode query string // We need this kind of encoder and decoder with optional [encType] argument String urlDecode(String s){ int i, p, q; var ol = new List<int>(); for (i = 0; i < s.length; i++) { if (s[i].charCodeAt(0) == 0x2b) ol.add(0x20); // convert + to space else if (s[i].charCodeAt(0) == 0x25) { // convert hex bytes to a single bite i++; p = s[i].toUpperCase().charCodeAt(0) - 0x30; if (p > 9) p = p - 7; i++; q = s[i].toUpperCase().charCodeAt(0) - 0x30; if (q > 9) q = q - 7; ol.add(p * 16 + q); } else ol.add(s[i].charCodeAt(0)); } return utf.decodeUtf8(ol); } // URL encoder encodes string into url encoded utf-8 bytes // Use this method to encode cookie string // or to write URL encoded byte data into OutputStream List<int> urlEncode(String s) { int i, p, q; var ol = new List<int>(); List<int> il = utf.encodeUtf8(s); for (i = 0; i < il.length; i++) { if (il[i] == 0x20) ol.add(0x2b); // convert sp to + else if (il[i] == 0x2a || il[i] == 0x2d || il[i] == 0x2e || il[i] == 0x5f) ol.add(il[i]); // do not convert else if (((il[i] >= 0x30) && (il[i] <= 0x39)) || ((il[i] >= 0x41) && (il[i] <= 0x5a)) || ((il[i] >= 0x61) && (il[i] <= 0x7a))) ol.add(il[i]); else { // '%' shift ol.add(0x25); ol.add((il[i] ~/ 0x10).toRadixString(16).charCodeAt(0)); ol.add((il[i] & 0xf).toRadixString(16).charCodeAt(0)); } } return ol; }
DumpHttpRequest.html
<!-- Send HTTP test request to the DumpHttpRequest server --> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>DumpHttpRequest</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!-- replace upper line with : <meta http-equiv="Content-Type" content="text/html; charset=windows-31j"> and compare the result --> </head> <body> <H1>Send text area value to the server</H1> <form method="post" action="http://localhost:8080/DumpHttpRequest" enctype="text/plain"> <!-- replace upper line with : <form method="post" action="http://localhost:8080/DumpHttpRequest"> and compare the result (default enctype is "application/x-www-form-urlencoded") --> <textarea rows="5" cols="80" name="submitPost"></textarea><br> <input type="submit" value="Submit using POST"> </form> <br> <form method="get" action="http://localhost:8080/DumpHttpRequest"> <textarea rows="5" cols="80" name="submitGet"></textarea><br> <input type="submit" value="Submit using GET"> </form> </body> </html>