Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
contactsamie committed Feb 14, 2020
1 parent e195295 commit b49051f
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 13 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ Another example, to return http:https://www.google.com content when only GET /google,
Another example, to return http:https://www.google.com content when only GET and the path and query ends with /google (not case sensitive) , then server.csv will contain

`EndsWith /google , http:https://www.google.com , GET`

Another example, when a POST comes in , turn around and make a GET request to the server

`EndsWith /google , http:https://www.google.com , POST - GET`

Wrap the result in a jsonp, useful if client makes a jsonp call but server is not setup to return jsonp

`EndsWith /google , http:https://www.google.com , GETJSONP`

Using filters : when a POST comes in , turn around and make a GET request to the server. When the result comes back, wrap it in jsonp (same effect as above)

`EndsWith /google , http:https://www.google.com , POST - GET | jsonp`

Another example, to return http:https://www.google.com content when only GET and the path and query starts with /google (not case sensitive) , then server.csv will contain

Expand Down
114 changes: 113 additions & 1 deletion ServeMe.Tests/when_serve_me_runs_in_memory_setup.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace ServeMe.Tests
using System;

namespace ServeMe.Tests
{
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -106,6 +108,113 @@ public void return_maprequestpathandquerytolink()
}
}


[TestMethod]
public void fails_on_a_post()
{
try
{
string serverCsv = @"getSome,http:https://www.google.com,post";
using (var serveMe = new ServeMe())
{
string url = serveMe.Start().First();
serveMe.AppendToInMemoryConfiguration(serverCsv);
HttpWebResponse result = (url + "/getSome").Post();
string finalResult = result.ReadStringFromResponse().Trim().ToLower();
Assert.IsTrue(finalResult.StartsWith("<!doc"));
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}
Assert.Fail();
}
catch (Exception e)
{

}
}
[TestMethod]
public void turns_arround_and_get_when_it_would_have_failed_on_a_post()
{
string serverCsv = @"getSome,http:https://www.google.com,post - get";
using (var serveMe = new ServeMe())
{
string url = serveMe.Start().First();
serveMe.AppendToInMemoryConfiguration(serverCsv);
HttpWebResponse result = (url + "/getSome").Post();
string finalResult = result.ReadStringFromResponse().Trim().ToLower();
Assert.IsTrue(finalResult.StartsWith("<!doc"));
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}
}
[TestMethod]
public void return_jsonp()
{
string serverCsv = @"getSome,http:https://www.google.com,get | jsonp";
using (var serveMe = new ServeMe())
{
string url = serveMe.Start().First();
serveMe.AppendToInMemoryConfiguration(serverCsv);
HttpWebResponse result = (url + "/getSome?callback=booo").Get();
string finalResult = result.ReadStringFromResponse().Trim().ToLower();
Assert.IsTrue(finalResult.StartsWith("booo(<!doc"));
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}
}
[TestMethod]
public void return_jsonp2()
{
string serverCsv = @"getSome,http:https://www.google.com,getjsonp";
using (var serveMe = new ServeMe())
{
string url = serveMe.Start().First();
serveMe.AppendToInMemoryConfiguration(serverCsv);
HttpWebResponse result = (url + "/getSome?callback=booo").Get();
string finalResult = result.ReadStringFromResponse().Trim().ToLower();
Assert.IsTrue(finalResult.StartsWith("booo(<!doc"));
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}
}
[TestMethod]
public void understand_query_parts()
{
string serverCsv = @"startswith / ,json {{0}}/{{scheme}}/{{3}}/{{4}}/{{5}}/{{file}}/{{6}}/{{query}}/{{extension}}/{{pathandquery}}/{{path}},get ";
using (var serveMe = new ServeMe())
{
string url = serveMe.Start().First();
serveMe.AppendToInMemoryConfiguration(serverCsv);
HttpWebResponse result = (url + "/let/us/go.php?w=tree").Get();
string finalResult = result.ReadStringFromResponse().Trim().ToLower();
Assert.IsTrue(finalResult == "http/http/let/us/go.php/go.php/w=tree/w=tree/.php//let/us/go.php?w=tree//let/us/go.php");
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}
}
[TestMethod]
public void understand_query_parts2()
{
string serverCsv = @"startswith / ,{{scheme}}:https://{{3}}.{{4}}.{{5}},get ";
using (var serveMe = new ServeMe())
{
string url = serveMe.Start().First();
serveMe.AppendToInMemoryConfiguration(serverCsv);
HttpWebResponse result = (url + "/www/google/com/us/go.php?w=tree").Get();
string finalResult = result.ReadStringFromResponse().Trim().ToLower();
Assert.IsTrue(finalResult.StartsWith("<!doc"));
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}
}
[TestMethod]
public void understand_query_parts3_on_steriods()
{
string serverCsv = @"{{6}} / ,{{scheme}}:https://{{3}}.{{4}}.{{5}} , {{7}} ";
using (var serveMe = new ServeMe())
{
string url = serveMe.Start().First();
serveMe.AppendToInMemoryConfiguration(serverCsv);
HttpWebResponse result = (url + "/www/google/com/startswith/get/us/go.php?w=tree").Get();
string finalResult = result.ReadStringFromResponse().Trim().ToLower();
Assert.IsTrue(finalResult.StartsWith("<!doc"));
Assert.AreEqual(HttpStatusCode.OK, result.StatusCode);
}
}
[TestMethod]
public void return_link_as_json()
{
Expand Down Expand Up @@ -231,6 +340,9 @@ public void it_can_return_json_string_provided_inline_with_get_and_ok_status_cod
}
}




[TestMethod]
public void it_can_return_json_string_provided_inline_with_get_and_accepted_status_code()
{
Expand Down
67 changes: 55 additions & 12 deletions ServeMeLib/SimpleHttpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

// MIT License - Copyright (c) 2016 Can Güney Aksakalli
// https://aksakalli.github.io/2014/02/24/simple-http-server-with-csparp.html

internal class SimpleHttpServer
{
private static readonly IDictionary<string, string> _mimeTypeMappings = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
Expand Down Expand Up @@ -342,6 +338,8 @@ private void Process(HttpListenerContext context)

string[] toParts = Regex.Split(parts[1].Trim(), @"\s{1,}");
string to = toParts[0].Trim();
to = replaceTokensForTo(to, context);

string[] toPossiblePartsPart = parts[1].Trim().Split(new[] { ' ' }, 2);
bool expectedJson = false;
string toFirstPart = toPossiblePartsPart[0].Trim().ToLower();
Expand Down Expand Up @@ -482,18 +480,30 @@ private void Process(HttpListenerContext context)
filename = to;
string expectedMethodFrom = "GET";
string methodTo = "GET";
string filter = null;
bool isJsonP = false;
if (parts.Length > 2)
if (!string.IsNullOrEmpty(parts[2].Trim()))
{
expectedMethodFrom = parts[2].Trim().ToUpper();

expectedMethodFrom = replaceTokensForTo(expectedMethodFrom, context);
if (expectedMethodFrom.Contains("|"))
{
string[] methodParts = expectedMethodFrom.Split('|');
expectedMethodFrom = string.IsNullOrEmpty(methodParts[0]) ? "GET" : methodParts[0];
methodTo = methodParts[1];
expectedMethodFrom = string.IsNullOrEmpty(methodParts[0]) ? "GET" : methodParts[0].Trim();
filter = methodParts[1].Trim();
}
if (expectedMethodFrom.Contains("-"))
{
string[] methodParts = expectedMethodFrom.Split('-');
expectedMethodFrom = string.IsNullOrEmpty(methodParts[0]) ? "GET" : methodParts[0].Trim();
methodTo = methodParts[1].Trim();
}
if (expectedMethodFrom.ToLower().Trim() == "getjsonp")
{
expectedMethodFrom = "GET";
isJsonP = true;
}

if (context.Request.HttpMethod.ToLower() != expectedMethodFrom.ToLower())
{
this.ServeMe.Log($"Found matching setting : {s}", "Returning \'NotFound\' status");
Expand Down Expand Up @@ -521,7 +531,7 @@ private void Process(HttpListenerContext context)
{
this.ServeMe.Log($"Found matching setting : {s}", $"Making external call to {to}");

HttpRequestMessage request = ToHttpRequestMessage(context.Request, to);
HttpRequestMessage request = ToHttpRequestMessage(context.Request, to, methodTo);

if (authType != null)
{
Expand Down Expand Up @@ -550,6 +560,36 @@ private void Process(HttpListenerContext context)
{
string stringResponse = response.Content.ReadAsStringAsync().Result;


if (!string.IsNullOrEmpty(filter))
{
filter = filter.ToLower().Trim();
//power of filters
if (filter == "tolower")
{
stringResponse = stringResponse.ToLower();
}
if (filter == "jsonp")
{
isJsonP = true;
}
}

if (isJsonP)
{
this.ServeMe.Log($"jsonp response requested");
var callback = context.Request.Url.ToString().Split(new char[] { '?', '&' }).Where(x => x.ToLower().StartsWith("callback=")).Select(x => x.Replace("callback=", "")).FirstOrDefault();
if (!string.IsNullOrEmpty(callback))
{
stringResponse = callback + "(" + stringResponse + ")";
this.ServeMe.Log($"jsonp formed!");
}
else
{
this.ServeMe.Log($"No jsonp callback could be inferred from the request");
}
}

stringResponse = this.ServeMe.ExecuteTemplate(stringResponse);

if (!string.IsNullOrEmpty(saveFile))
Expand Down Expand Up @@ -714,7 +754,7 @@ private static string replaceTokensForTo(string to, HttpListenerContext context)
to = to.Replace("{{host}}", context.Request.Url.Host.ToString());
to = to.Replace("{{pathandquery}}", context.Request.Url.PathAndQuery.ToString());
to = to.Replace("{{path}}", context.Request.Url.AbsolutePath.ToString());
to = to.Replace("{{extension}}", Path.GetExtension(context.Request.Url.ToString()));
to = to.Replace("{{extension}}", Path.GetExtension(context.Request.Url.ToString()).Split('?')[0]);
to = to.Replace("{{noscheme}}", context.Request.Url.ToString().Replace(context.Request.Url.Scheme + ":https://", ""));
to = to.Replace("{{httpurl}}", context.Request.Url.ToString().Replace(context.Request.Url.Scheme + ":https://", "http:https://"));
to = to.Replace("{{httpsurl}}", context.Request.Url.ToString().Replace(context.Request.Url.Scheme + ":https://", "https://"));
Expand Down Expand Up @@ -764,6 +804,9 @@ private void Initialize(string path, int port)
try
{
//todo using task run here now, but it needs to be refactored for performance
request.Headers.AcceptEncoding.Clear();
request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
HttpResponseMessage response = Task.Run(() => client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)).Result;

response.Headers.Via.Add(new ViaHeaderValue("1.2", "ServeMeProxy", "http"));
Expand Down Expand Up @@ -826,9 +869,9 @@ private void Initialize(string path, int port)
}
}

private static HttpRequestMessage ToHttpRequestMessage(HttpListenerRequest requestInfo, string RewriteToUrl)
private static HttpRequestMessage ToHttpRequestMessage(HttpListenerRequest requestInfo, string RewriteToUrl, string HttpMethodStr=null)
{
var method = new HttpMethod(requestInfo.HttpMethod);
var method = new HttpMethod(HttpMethodStr??requestInfo.HttpMethod);

var request = new HttpRequestMessage(method, RewriteToUrl);

Expand Down

0 comments on commit b49051f

Please sign in to comment.