Commit 33b3586e authored by Honfika's avatar Honfika

Show request and response texts in demo app

parent 47ba3eca
...@@ -29,5 +29,17 @@ ...@@ -29,5 +29,17 @@
</GridView> </GridView>
</ListView.View> </ListView.View>
</ListView> </ListView>
<TabControl Grid.Column="2">
<TabItem Header="Session">
<Grid Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox x:Name="TextBoxRequest" Grid.Row="0" />
<TextBox x:Name="TextBoxResponse" Grid.Row="1" />
</Grid>
</TabItem>
</TabControl>
</Grid> </Grid>
</Window> </Window>
...@@ -29,11 +29,23 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -29,11 +29,23 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private int lastSessionNumber; private int lastSessionNumber;
public ObservableCollection<SessionListItem> Sessions { get; } = new ObservableCollection<SessionListItem>(); public ObservableCollection<SessionListItem> Sessions { get; } = new ObservableCollection<SessionListItem>();
public SessionListItem SelectedSession { get; set; } public SessionListItem SelectedSession
{
get { return selectedSession; }
set
{
if (value != selectedSession)
{
selectedSession = value;
SelectedSessionChanged();
}
}
}
private readonly Dictionary<SessionEventArgs, SessionListItem> sessionDictionary = new Dictionary<SessionEventArgs, SessionListItem>(); private readonly Dictionary<SessionEventArgs, SessionListItem> sessionDictionary = new Dictionary<SessionEventArgs, SessionListItem>();
private SessionListItem selectedSession;
public MainWindow() public MainWindow()
{ {
...@@ -76,29 +88,47 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -76,29 +88,47 @@ namespace Titanium.Web.Proxy.Examples.Wpf
private async Task ProxyServer_BeforeRequest(object sender, SessionEventArgs e) private async Task ProxyServer_BeforeRequest(object sender, SessionEventArgs e)
{ {
SessionListItem item = null;
Dispatcher.Invoke(() => Dispatcher.Invoke(() =>
{ {
AddSession(e); item = AddSession(e);
}); });
if (e.WebSession.Request.HasBody)
{
item.RequestBody = await e.GetRequestBody();
}
} }
private async Task ProxyServer_BeforeResponse(object sender, SessionEventArgs e) private async Task ProxyServer_BeforeResponse(object sender, SessionEventArgs e)
{ {
SessionListItem item = null;
Dispatcher.Invoke(() => Dispatcher.Invoke(() =>
{ {
SessionListItem item; SessionListItem item2;
if (sessionDictionary.TryGetValue(e, out item)) if (sessionDictionary.TryGetValue(e, out item2))
{ {
item.Update(); item2.Response.ResponseStatusCode = e.WebSession.Response.ResponseStatusCode;
item2.Response.ResponseStatusDescription = e.WebSession.Response.ResponseStatusDescription;
item2.Response.HttpVersion = e.WebSession.Response.HttpVersion;
item2.Response.ResponseHeaders.AddHeaders(e.WebSession.Response.ResponseHeaders);
item2.Update();
item = item2;
} }
}); });
if (item != null)
{
item.ResponseBody = await e.GetResponseBody();
}
} }
private void AddSession(SessionEventArgs e) private SessionListItem AddSession(SessionEventArgs e)
{ {
var item = CreateSessionListItem(e); var item = CreateSessionListItem(e);
Sessions.Add(item); Sessions.Add(item);
sessionDictionary.Add(e, item); sessionDictionary.Add(e, item);
return item;
} }
private SessionListItem CreateSessionListItem(SessionEventArgs e) private SessionListItem CreateSessionListItem(SessionEventArgs e)
...@@ -108,8 +138,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -108,8 +138,16 @@ namespace Titanium.Web.Proxy.Examples.Wpf
{ {
Number = lastSessionNumber, Number = lastSessionNumber,
SessionArgs = e, SessionArgs = e,
Request =
{
Method = e.WebSession.Request.Method,
RequestUri = e.WebSession.Request.RequestUri,
HttpVersion = e.WebSession.Request.HttpVersion,
},
}; };
item.Request.RequestHeaders.AddHeaders(e.WebSession.Request.RequestHeaders);
if (e is TunnelConnectSessionEventArgs) if (e is TunnelConnectSessionEventArgs)
{ {
e.DataReceived += (sender, args) => e.DataReceived += (sender, args) =>
...@@ -137,27 +175,38 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -137,27 +175,38 @@ namespace Titanium.Web.Proxy.Examples.Wpf
return item; return item;
} }
private void Session_DataReceived(object sender, EventArgs e) private void ListViewSessions_OnKeyDown(object sender, KeyEventArgs e)
{ {
Dispatcher.Invoke(() => if (e.Key == Key.Delete)
{ {
var session = (SessionEventArgs)sender; var selectedItems = ((ListView)sender).SelectedItems;
SessionListItem item; foreach (var item in selectedItems.Cast<SessionListItem>().ToArray())
if (sessionDictionary.TryGetValue(session, out item))
{ {
item.Update(); Sessions.Remove(item);
sessionDictionary.Remove(item.SessionArgs);
} }
}); }
} }
private void ListViewSessions_OnKeyDown(object sender, KeyEventArgs e) private void SelectedSessionChanged()
{ {
var selectedItems = ((ListView)sender).SelectedItems; if (SelectedSession == null)
foreach (var item in selectedItems.Cast<SessionListItem>().ToArray())
{ {
Sessions.Remove(item); return;
sessionDictionary.Remove(item.SessionArgs);
} }
var session = SelectedSession;
var data = session.RequestBody ?? new byte[0];
data = data.Take(1024).ToArray();
string dataStr = string.Join(" ", data.Select(x => x.ToString("X2")));
TextBoxRequest.Text = session.Request.HeaderText + dataStr;
data = session.ResponseBody ?? new byte[0];
data = data.Take(1024).ToArray();
dataStr = string.Join(" ", data.Select(x => x.ToString("X2")));
TextBoxResponse.Text = session.Response.HeaderText + dataStr;
} }
} }
} }
...@@ -7,6 +7,7 @@ using System.Text; ...@@ -7,6 +7,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Examples.Wpf.Annotations; using Titanium.Web.Proxy.Examples.Wpf.Annotations;
using Titanium.Web.Proxy.Http;
namespace Titanium.Web.Proxy.Examples.Wpf namespace Titanium.Web.Proxy.Examples.Wpf
{ {
...@@ -73,6 +74,14 @@ namespace Titanium.Web.Proxy.Examples.Wpf ...@@ -73,6 +74,14 @@ namespace Titanium.Web.Proxy.Examples.Wpf
set { SetField(ref sentDataCount, value); } set { SetField(ref sentDataCount, value); }
} }
public byte[] RequestBody { get; set; }
public byte[] ResponseBody { get; set; }
public Request Request { get; set; } = new Request();
public Response Response { get; set; } = new Response();
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
protected void SetField<T>(ref T field, T value,[CallerMemberName] string propertyName = null) protected void SetField<T>(ref T field, T value,[CallerMemberName] string propertyName = null)
......
...@@ -286,15 +286,7 @@ namespace Titanium.Web.Proxy.EventArguments ...@@ -286,15 +286,7 @@ namespace Titanium.Web.Proxy.EventArguments
} }
WebSession.Request.RequestBody = body; WebSession.Request.RequestBody = body;
WebSession.Request.ContentLength = WebSession.Request.IsChunked ? -1 : body.Length;
if (WebSession.Request.IsChunked == false)
{
WebSession.Request.ContentLength = body.Length;
}
else
{
WebSession.Request.ContentLength = -1;
}
} }
/// <summary> /// <summary>
......
...@@ -183,24 +183,22 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -183,24 +183,22 @@ namespace Titanium.Web.Proxy.Helpers
if (httpCmd != null || requestHeaders != null) if (httpCmd != null || requestHeaders != null)
{ {
using (var ms = new MemoryStream()) using (var ms = new MemoryStream())
using (var writer = new StreamWriter(ms, Encoding.ASCII)) using (var writer = new StreamWriter(ms, Encoding.ASCII) { NewLine = ProxyConstants.NewLine })
{ {
if (httpCmd != null) if (httpCmd != null)
{ {
writer.Write(httpCmd); writer.WriteLine(httpCmd);
writer.Write(ProxyConstants.NewLine);
} }
if (requestHeaders != null) if (requestHeaders != null)
{ {
foreach (string header in requestHeaders.Select(t => t.ToString())) foreach (string header in requestHeaders.Select(t => t.ToString()))
{ {
writer.Write(header); writer.WriteLine(header);
writer.Write(ProxyConstants.NewLine);
} }
} }
writer.Write(ProxyConstants.NewLine); writer.WriteLine();
writer.Flush(); writer.Flush();
var data = ms.ToArray(); var data = ms.ToArray();
......
...@@ -3,7 +3,6 @@ using System.Collections.Generic; ...@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Titanium.Web.Proxy.Extensions; using Titanium.Web.Proxy.Extensions;
using Titanium.Web.Proxy.Models;
namespace Titanium.Web.Proxy.Http namespace Titanium.Web.Proxy.Http
{ {
...@@ -52,13 +51,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -52,13 +51,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Content encoding header value /// Content encoding header value
/// </summary> /// </summary>
public string ContentEncoding public string ContentEncoding => RequestHeaders.GetHeaderValueOrNull("content-encoding");
{
get
{
return RequestHeaders.GetHeaderValueOrNull("content-encoding");
}
}
/// <summary> /// <summary>
/// Request content-length /// Request content-length
...@@ -169,7 +162,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -169,7 +162,7 @@ namespace Titanium.Web.Proxy.Http
internal byte[] RequestBody { get; set; } internal byte[] RequestBody { get; set; }
/// <summary> /// <summary>
/// request body as string /// Request body as string
/// </summary> /// </summary>
internal string RequestBodyString { get; set; } internal string RequestBodyString { get; set; }
...@@ -204,7 +197,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -204,7 +197,7 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Request header collection /// Request header collection
/// </summary> /// </summary>
public HeaderCollection RequestHeaders { get; set; } public HeaderCollection RequestHeaders { get; private set; } = new HeaderCollection();
/// <summary> /// <summary>
/// Does server responsed positively for 100 continue request /// Does server responsed positively for 100 continue request
...@@ -216,12 +209,30 @@ namespace Titanium.Web.Proxy.Http ...@@ -216,12 +209,30 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
public bool ExpectationFailed { get; internal set; } public bool ExpectationFailed { get; internal set; }
/// <summary>
/// Gets the header text.
/// </summary>
public string HeaderText
{
get
{
var sb = new StringBuilder();
sb.AppendLine($"{Method} {RequestUri.PathAndQuery} HTTP/{HttpVersion.Major}.{HttpVersion.Minor}");
foreach (var header in RequestHeaders)
{
sb.AppendLine(header.ToString());
}
sb.AppendLine();
return sb.ToString();
}
}
/// <summary> /// <summary>
/// Constructor. /// Constructor.
/// </summary> /// </summary>
public Request() public Request()
{ {
RequestHeaders = new HeaderCollection();
} }
/// <summary> /// <summary>
...@@ -235,7 +246,7 @@ namespace Titanium.Web.Proxy.Http ...@@ -235,7 +246,7 @@ namespace Titanium.Web.Proxy.Http
RequestHeaders = null; RequestHeaders = null;
RequestBody = null; RequestBody = null;
RequestBody = null; RequestBodyString = null;
} }
} }
} }
...@@ -127,15 +127,15 @@ namespace Titanium.Web.Proxy.Http ...@@ -127,15 +127,15 @@ namespace Titanium.Web.Proxy.Http
/// <summary> /// <summary>
/// Collection of all response headers /// Collection of all response headers
/// </summary> /// </summary>
public HeaderCollection ResponseHeaders { get; set; } public HeaderCollection ResponseHeaders { get; private set; } = new HeaderCollection();
/// <summary> /// <summary>
/// response body content as byte array /// Response body content as byte array
/// </summary> /// </summary>
internal byte[] ResponseBody { get; set; } internal byte[] ResponseBody { get; set; }
/// <summary> /// <summary>
/// response body as string /// Response body as string
/// </summary> /// </summary>
internal string ResponseBodyString { get; set; } internal string ResponseBodyString { get; set; }
...@@ -159,12 +159,35 @@ namespace Titanium.Web.Proxy.Http ...@@ -159,12 +159,35 @@ namespace Titanium.Web.Proxy.Http
/// </summary> /// </summary>
public bool ExpectationFailed { get; internal set; } public bool ExpectationFailed { get; internal set; }
/// <summary>
/// Gets the resposne status.
/// </summary>
public string ResponseStatus => $"HTTP/{HttpVersion?.Major}.{HttpVersion?.Minor} {ResponseStatusCode} {ResponseStatusDescription}";
/// <summary>
/// Gets the header text.
/// </summary>
public string HeaderText
{
get
{
var sb = new StringBuilder();
sb.AppendLine(ResponseStatus);
foreach (var header in ResponseHeaders)
{
sb.AppendLine(header.ToString());
}
sb.AppendLine();
return sb.ToString();
}
}
/// <summary> /// <summary>
/// Constructor. /// Constructor.
/// </summary> /// </summary>
public Response() public Response()
{ {
ResponseHeaders = new HeaderCollection();
} }
/// <summary> /// <summary>
......
...@@ -9,9 +9,9 @@ namespace Titanium.Web.Proxy.Models ...@@ -9,9 +9,9 @@ namespace Titanium.Web.Proxy.Models
/// </summary> /// </summary>
public class HttpHeader public class HttpHeader
{ {
internal static Version Version10 = new Version(1, 0); internal static readonly Version Version10 = new Version(1, 0);
internal static Version Version11 = new Version(1, 1); internal static readonly Version Version11 = new Version(1, 1);
/// <summary> /// <summary>
/// Constructor. /// Constructor.
......
...@@ -335,7 +335,7 @@ namespace Titanium.Web.Proxy ...@@ -335,7 +335,7 @@ namespace Titanium.Web.Proxy
break; break;
} }
PrepareRequestHeaders(args.WebSession.Request.RequestHeaders, args.WebSession); PrepareRequestHeaders(args.WebSession.Request.RequestHeaders);
args.WebSession.Request.Host = args.WebSession.Request.RequestUri.Authority; args.WebSession.Request.Host = args.WebSession.Request.RequestUri.Authority;
//if win auth is enabled //if win auth is enabled
...@@ -474,6 +474,7 @@ namespace Titanium.Web.Proxy ...@@ -474,6 +474,7 @@ namespace Titanium.Web.Proxy
args.WebSession.Request.RequestBody = args.WebSession.Request.RequestBody =
await GetCompressedResponseBody(args.WebSession.Request.ContentEncoding, args.WebSession.Request.RequestBody); await GetCompressedResponseBody(args.WebSession.Request.ContentEncoding, args.WebSession.Request.RequestBody);
} }
//chunked send is not supported as of now //chunked send is not supported as of now
args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length; args.WebSession.Request.ContentLength = args.WebSession.Request.RequestBody.Length;
...@@ -595,8 +596,7 @@ namespace Titanium.Web.Proxy ...@@ -595,8 +596,7 @@ namespace Titanium.Web.Proxy
/// prepare the request headers so that we can avoid encodings not parsable by this proxy /// prepare the request headers so that we can avoid encodings not parsable by this proxy
/// </summary> /// </summary>
/// <param name="requestHeaders"></param> /// <param name="requestHeaders"></param>
/// <param name="webRequest"></param> private void PrepareRequestHeaders(HeaderCollection requestHeaders)
private void PrepareRequestHeaders(HeaderCollection requestHeaders, HttpWebClient webRequest)
{ {
foreach (var header in requestHeaders) foreach (var header in requestHeaders)
{ {
...@@ -610,7 +610,6 @@ namespace Titanium.Web.Proxy ...@@ -610,7 +610,6 @@ namespace Titanium.Web.Proxy
} }
FixProxyHeaders(requestHeaders); FixProxyHeaders(requestHeaders);
webRequest.Request.RequestHeaders = requestHeaders;
} }
/// <summary> /// <summary>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment