/// <summary> /// Create response form object /// </summary> /// <param name="value"></param> /// <returns></returns> private static webResposne createResponse(object value) { //json var json = JsonConvert.SerializeObject(value, new StringEnumConverter()); var stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); writer.Write(json); writer.Flush(); stream.Seek(0, SeekOrigin.Begin); //response var response = new IDCT.webResposne(); response.content = stream; response.header = new Dictionary<string, string>(); response.header.Add("Content-Type", "text/json"); return response; }
/// <summary> /// Load file /// </summary> /// <returns></returns> private Task<webResposne> loadFile(String url) { //create var response = new IDCT.webResposne(); //remove ? if (url.IndexOf("?") > -1) { url = url.Substring(0, url.IndexOf("?")); } //set headers response.header = new Dictionary<string, string>(); //load resource var uri = new Uri("Interface/" + url, UriKind.Relative); var resource = App.GetResourceStream(uri); if (resource != null) { response.content = resource.Stream; response.header.Add("Content-Type", contentType(uri)); } else { return e404(); } //send return Task.FromResult(response); }
/// <summary> /// Error 404 /// </summary> /// <returns></returns> private Task<webResposne> e404() { //create var response = new IDCT.webResposne(); //set headers response.header = new Dictionary<string, string>(); //stream var stream = new MemoryStream(); var stremWriter = new StreamWriter(stream); stremWriter.Write("<meta http-equiv=\"refresh\" content=\"0; url=" + this.Url + "\" />"); stremWriter.Flush(); stream.Seek(0, SeekOrigin.Begin); response.content = stream; response.header.Add("Content-Type", "text/html"); //send return Task.FromResult(response); }
/// <summary> /// Get skin /// </summary> /// <returns></returns> private Task<webResposne> skin() { //json var json = JsonConvert.SerializeObject(this.skinData); var stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); writer.Write(json); writer.Flush(); stream.Seek(0, SeekOrigin.Begin); //response var response = new IDCT.webResposne(); response.content = stream; response.header = new Dictionary<string, string>(); response.header.Add("Content-Type", "text/json"); return Task.FromResult(response); }
/// <summary> /// Language /// </summary> /// <returns></returns> private Task<webResposne> language() { var test = AppResources.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, false); if (test == null) { test = AppResources.ResourceManager.GetResourceSet(System.Globalization.CultureInfo.InvariantCulture, true, false); } //json var json = JsonConvert.SerializeObject(test); var stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); writer.Write(json); writer.Flush(); stream.Seek(0, SeekOrigin.Begin); //response var response = new IDCT.webResposne(); response.content = stream; response.header = new Dictionary<string, string>(); response.header.Add("Content-Type", "text/json"); return Task.FromResult(response); }
/// <summary> /// method which parses the request and decides about the action /// </summary> /// <param name="request_file">path to the temporary file holding the request packet</param> /// <param name="socket">socket used with the request (required for response)</param> public void parseRequest(string request_file, StreamSocket socket) { //open and read the request: needs stream reading support for large files IsolatedStorageFileStream plika = isf.OpenFile(request_file, FileMode.Open); StreamReader reada = new StreamReader(plika); //read the first ling to get request type string linge = reada.ReadLine(); //create new request object (same type as response object - possibly better class naming needs to be used) webResposne request = new webResposne(); //if there is any data... if (linge != null && linge.Length > 0) { //get the method (currently GET only supported really) and the request URL if (linge.Substring(0, 3) == "GET") { request.method = "GET"; request.uri = linge.Substring(4); } else if (linge.Substring(0, 4) == "POST") { request.method = "POST"; request.uri = linge.Substring(5); } //remove the HTTP version request.uri = Regex.Replace(request.uri, " HTTP.*$", ""); //create a dictionary for the sent headers Dictionary<string, string> headers = new Dictionary<string, string>(); //read HTTP headers into the dictionary string line = ""; do { line = reada.ReadLine(); string[] sepa = new string[1]; sepa[0] = ":"; string[] elems = line.Split(sepa, 2, StringSplitOptions.RemoveEmptyEntries); if (elems.Length > 0) { headers.Add(elems[0], elems[1]); } } while (line.Length > 0); //assign headers to the request object request.header = headers; //assigne rest of the content to the request object in a form of a stream handle moved to the part with content after previous read line operations request.content = reada.BaseStream; //determines if we found a matching URL rule bool foundrule = false; //create a stream writer to the output stream (response) DataWriter writ = new DataWriter(socket.OutputStream); //if there are any server rules if (serverRules != null) { //for every rule... foreach (Regex rule_part in serverRules.Keys) { //if it matches the URL if (rule_part.IsMatch(request.uri)) { //create a new response object //assign to it response from the method called as a delegate assigned to the URL rule webResposne toSend = serverRules[rule_part](request); //mark that we found a rule foundrule = true; //if the rule is meant to redirect... if (toSend.header.ContainsKey("Location")) { writ.WriteString("HTTP/1.1 302\r\n"); } else //if a normal read operation { writ.WriteString("HTTP/1.1 200 OK\r\n"); } //write content length to the buffer writ.WriteString("Content-Length: " + toSend.content.Length + "\r\n"); //for each of the response headers (returned by the delegate assigned to the URL rule foreach (string key in toSend.header.Keys) { //write it to the output writ.WriteString(key + ": " + toSend.header[key] + "\r\n"); } //add connection: close header writ.WriteString("Connection: close\r\n"); //new line before writing content writ.WriteString("\r\n"); //we lock the webserver until response is finished lock (this) { //reset the output stream toSend.content.Seek(0, SeekOrigin.Begin); Task.Run(async () => { await writ.StoreAsync(); //wait for the data to be saved in the output await writ.FlushAsync(); //flush (send to the output) //write the data to the output using 1024 buffer (store and flush after every loop) while (toSend.content.Position < toSend.content.Length) { byte[] buffer; if (toSend.content.Length - toSend.content.Position < 1024) { buffer = new byte[toSend.content.Length - toSend.content.Position]; } else { buffer = new byte[1024]; } toSend.content.Read(buffer, 0, buffer.Length); writ.WriteBytes(buffer); await writ.StoreAsync(); await writ.FlushAsync(); } toSend.content.Close(); }); } break; } } } if (foundrule == false) { writ.WriteString("HTTP/1.1 404 Not Found\r\n"); writ.WriteString("Content-Type: text/html\r\n"); writ.WriteString("Content-Length: 9\r\n"); writ.WriteString("Pragma: no-cache\r\n"); writ.WriteString("Connection: close\r\n"); writ.WriteString("\r\n"); writ.WriteString("Not found"); Task.Run(async () => { await writ.StoreAsync(); }); } } }
webResposne homePage(webResposne request) { //prepare the response object webResposne newResponse = new webResposne(); //create a new dictionary for headers - this could be done using a more advanced class for webResponse object - i just used a simple struct newResponse.header = new Dictionary<string, string>(); //add content type header newResponse.header.Add("Content-Type", "text/html"); Stream resposneText = new MemoryStream(); StreamWriter contentWriter = new StreamWriter(resposneText); contentWriter.WriteLine("<html>"); contentWriter.WriteLine(" <head>"); contentWriter.WriteLine(" <title>Sample response</title>"); contentWriter.WriteLine(" </head>"); contentWriter.WriteLine(" <body>"); contentWriter.WriteLine(" <p>Phone info:</p>"); contentWriter.WriteLine(" <p><b>Platform: </b>" + Environment.OSVersion.Platform + "</p>"); contentWriter.WriteLine(" <p><b>Device Name: </b>" + Microsoft.Phone.Info.DeviceStatus.DeviceName + "</p>"); contentWriter.WriteLine(" <p>Download file</p>"); contentWriter.WriteLine(" <p><a href='/files/test_file.txt'>get file</a></p>"); contentWriter.WriteLine(" </body>"); contentWriter.WriteLine("</html>"); contentWriter.Flush(); //assign the response newResponse.content = resposneText; //return the response return newResponse; }
webResposne getfile(webResposne request) { webResposne newResponse = new webResposne(); newResponse.header = new Dictionary<string, string>(); Stream resposneText = new MemoryStream(); //get the file name from the uri by removing the prefix string filename = request.uri.Replace("/files/", ""); if (isf.FileExists("/" + filename)) { //set thea content type header newResponse.header.Add("Content-Type", "binary/octet-stream"); //inform that it is going to be a download with a filename as in the request newResponse.header.Add("Content-Disposition", "attachment; filename=" + filename); //assign the file to the request resposneText = isf.OpenFile("/" + filename, FileMode.Open); } else { //file not found newResponse.header.Add("Content-Type", "text/html"); StreamWriter contentWriter = new StreamWriter(resposneText); contentWriter.WriteLine("<html>"); contentWriter.WriteLine(" <head>"); contentWriter.WriteLine(" <title>Not found</title>"); contentWriter.WriteLine(" </head>"); contentWriter.WriteLine(" <body>"); contentWriter.WriteLine(" <p>File not found</p>"); contentWriter.WriteLine(" </body>"); contentWriter.WriteLine("</html>"); contentWriter.Flush(); //assign the response newResponse.content = resposneText; } newResponse.content = resposneText; return newResponse; }