using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TEST
{
class Param
{
public HttpListenerContext ctx { get; set; }
public string url;
public string method;
public string query;
public string header;
}
class Program
{
static Dictionary<string, string> dic;
static Dictionary<string, JObject> reqID;
//static async Task Main(string[] args)
static void Main(string[] args)
{
string jInput;
if (args.Length > 0)
jInput = args[0];
else
jInput = ".\\Proxy.jon"; //// //args[0];
Console.WriteLine(jInput);
string jFile = ReadFile(jInput);
JObject json = JObject.Parse(jFile);
int port = (int)json["port"];
JArray routes = (JArray)json["routes"];
Console.WriteLine("port " + port.ToString());
dic = new Dictionary<string, string>();
reqID = new Dictionary<string, JObject>();
// HttpListener 객체를 생성하고, 웹 서버 주소를 설정합니다.
HttpListener listener = new HttpListener();
foreach (JObject jobj in routes)
{
Console.WriteLine("- " + jobj["pathPrefix"]);
Console.WriteLine("- " + jobj["url"]);
dic.Add((string)jobj["pathPrefix"], (string)jobj["url"]);
string temp = "http://127.0.0.1:" + port.ToString() + jobj["pathPrefix"] + "/";
Console.WriteLine(temp);
listener.Prefixes.Add(temp);
string trace = "http://127.0.0.1:" + port.ToString() + "/trace/";
listener.Prefixes.Add(trace);
}
try
{
// 웹 서버를 시작합니다.
listener.Start();
Console.WriteLine("웹 서버가 시작되었습니다.");
while (true)
{
// 클라이언트 요청을 받아들입니다.
HttpListenerContext ctx = listener.GetContext();
string uri = ctx.Request.Url.ToString();
string url = ctx.Request.RawUrl.ToString();
string path = ctx.Request.RawUrl.ToString();
string query = "";
string urlKey = "";
Console.WriteLine("uri " + uri);
Console.WriteLine("url " + url);
Console.WriteLine("path " + path);
if (path.Contains("?"))
{
urlKey = path.Split('?')[0];
query = path.Split('?')[1];
}
else
urlKey = path;
if (urlKey.Split('/').Length > 2)
urlKey = "/" + urlKey.Split('/')[1];
string method = ctx.Request.HttpMethod;
Console.WriteLine("query " + query);
if(dic.ContainsKey(urlKey))
Console.WriteLine("dic[urlKey] " + dic[urlKey]);
Console.WriteLine("target " + uri);
AppendLogToFile("log.txt", "target " + uri);
/*if (uri.Contains("http://127.0.0.1:5020/aut"))
{
Console.WriteLine("uri " + uri);
}*/
Param param = new Param();
param.ctx = ctx;
if (dic.ContainsKey(urlKey))
param.url = dic[urlKey] + url;
else
param.url = url;
param.method = method;
param.query = query;
//param.header = ctx.Request.Headers.Get("x-requestId");
int count = ctx.Request.Headers.AllKeys.Length;
for(int i=0; i<count; i++)
{
Console.WriteLine("Header Key:"+ctx.Request.Headers.Keys.Get(i));
}
JObject obj = new JObject(
new JProperty("target", param.url),
new JProperty("status", "200")
);
//reqID.Add(param.header, param.url);
Thread myThread = new Thread(requURL);
myThread.Start(param);
//await requestURL(param);
//Task.Run(() => requestURL(param)).Wait();
}
}
catch (Exception ex)
{
Console.WriteLine("웹 서버 오류: " + ex.Message);
}
finally
{
// 웹 서버를 종료합니다.
listener.Stop();
Console.WriteLine("웹 서버가 종료되었습니다.");
}
}
static void requURL(object _param)
{
Param param = (Param)_param;
HttpListenerContext ctx = param.ctx;
Task.Run(() => requestURL(param)).Wait();
}
static async Task requestURL(Param _param)
{
Param param = (Param)_param;
HttpListenerContext ctx = param.ctx;
try
{
string responseString = "";
HttpClient httpClient = new HttpClient();
string res = string.Empty;
HttpStatusCode statusCode = HttpStatusCode.OK;
httpClient.DefaultRequestHeaders.Add("x-requestId", param.header);
if (param.method == "GET")
{
string sendUrl = param.url+param.header;
if (param.query != "")
{
//sendUrl += "?" + param.query;
}
Console.WriteLine("service :" + sendUrl);
AppendLogToFile("log.txt", "service " + sendUrl);
HttpResponseMessage resp = await httpClient.GetAsync(sendUrl);
statusCode = resp.StatusCode;
responseString = await resp.Content.ReadAsStringAsync();
//Console.WriteLine("responseString " + );
//resp.Headers.TryGetValues(, out var headerValues);
}
else
{
HttpContent httpContent = new StringContent("", Encoding.UTF8, "application/json");
string sendUrl = param.url + param.header;
Console.WriteLine("service :" + sendUrl);
AppendLogToFile("log.txt", "service " + sendUrl);
HttpResponseMessage resp = await httpClient.PostAsync(sendUrl, httpContent);
resp.EnsureSuccessStatusCode(); // 성공적인 응답인지 확인
statusCode = resp.StatusCode;
responseString = await resp.Content.ReadAsStringAsync();
//resp.Headers.TryGetValues("x-requestId", out var headerValues);
/*if (response.Headers.TryGetValues(headerName, out var headerValues))
{
foreach (var value in headerValues)
{
Console.WriteLine($"{headerName}: {value}");
}
}
else
{
Console.WriteLine($"Header '{headerName}' not found in the response");
}*/
}
byte[] responseBytes = Encoding.UTF8.GetBytes(responseString);
// 응답 헤더를 설정합니다.
HttpListenerResponse response = ctx.Response;
response.StatusCode = (int)statusCode;
//response.ContentType = client.Headers["Content-Type"];
response.ContentLength64 = responseBytes.Length;
response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
response.OutputStream.Close();
}
catch (WebException ex)
{
HttpWebResponse resp = (HttpWebResponse)ex.Response;
ctx.Response.StatusCode = (int)resp.StatusCode;
ctx.Response.OutputStream.Close();
}
}
static async Task SendPostRequest(string url, string requestBody)
{
using (HttpClient httpClient = new HttpClient())
{
HttpContent httpContent = new StringContent(requestBody, Encoding.UTF8, "application/json");
HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
response.EnsureSuccessStatusCode(); // 성공적인 응답인지 확인
Console.WriteLine("POST request sent successfully");
}
}
static void reqURL(object _param)
{
Param param = (Param)_param;
HttpListenerContext ctx = param.ctx;
try
{
string responseString = "";
WebClient client = new WebClient();
string res = string.Empty;
if (param.method == "GET")
{
string sendUrl = param.url;
if (param.query != "") sendUrl += "?" + param.query;
Console.WriteLine("sendUrl :" + sendUrl);
responseString = client.DownloadString(sendUrl);
Console.WriteLine("responseString " + responseString);
}
else
{
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
responseString = client.UploadString(param.url, "");
}
// 클라이언트에게 응답을 보낼 데이터를 생성합니다.
HttpStatusCode statusCode = HttpStatusCode.OK; // 기본적으로 성공으로 가정
if (client.ResponseHeaders is WebHeaderCollection headers && headers.Count > 0)
{
// 응답 헤더에서 StatusCode 추출
if (Enum.TryParse(headers.Get(0), out HttpStatusCode parsedStatusCode))
{
statusCode = parsedStatusCode;
}
}
byte[] responseBytes = Encoding.UTF8.GetBytes(responseString);
// 응답 헤더를 설정합니다.
HttpListenerResponse response = ctx.Response;
response.StatusCode = (int)statusCode;
response.ContentType = client.Headers["Content-Type"];
response.ContentLength64 = responseBytes.Length;
response.OutputStream.Write(responseBytes, 0, responseBytes.Length);
response.OutputStream.Close();
}
catch (WebException ex)
{
HttpWebResponse resp = (HttpWebResponse)ex.Response;
ctx.Response.StatusCode = (int)resp.StatusCode;
ctx.Response.OutputStream.Close();
}
}
static string ReadFile(string filePath)
{
try
{
// 파일을 읽기 위해 StreamReader를 사용합니다.
using (StreamReader reader = new StreamReader(filePath))
{
// 파일의 모든 내용을 문자열로 읽어옵니다.
string content = reader.ReadToEnd();
return content;
}
}
catch (FileNotFoundException)
{
Console.WriteLine("파일을 찾을 수 없습니다.");
}
catch (Exception ex)
{
Console.WriteLine("파일 읽기 오류: " + ex.Message);
}
return null;
}
public static void AppendLogToFile(string logFilePath, string logMessage)
{
try
{
// 기존 파일이 존재하면 Append 모드로 열기
using (StreamWriter writer = new StreamWriter(logFilePath, true))
{
// 로그 메시지를 파일에 추가
writer.WriteLine(logMessage);
}
Console.WriteLine("로그가 파일에 추가되었습니다.");
}
catch (Exception ex)
{
Console.WriteLine($"로그 파일에 추가하는 중에 오류가 발생했습니다: {ex.Message}");
}
}
}
}
반응형