Показаны сообщения с ярлыком Fiddler. Показать все сообщения
Показаны сообщения с ярлыком Fiddler. Показать все сообщения

Как перехватить трафик ASP.NET Development Server'а

пятница, 24 апреля 2009 г.,

Ситуация: ASP.NET Development Server работает по адресу http://localhost:3840; требуется перехватить все запросы и ответы сервера.

Решение:
1) во всех адресах заменить "localhost" на "ipv4.fiddler". Например, вместо http://localhost:3840/Provider.svc/Now указать http://ipv4.fiddler:3840/Provider.svc/Now
2) запустить Fiddler (см. Install Fiddler2).

Запросы можно увидеть в окне Fiddler'а во вкладке Session Inspector - Raw, а на ответы можно посмотреть в нижней части вкладки, также нажав Raw.

ASP.NET Development Server находится в C:\Program Files\Common Files\microsoft shared\DevServer\9.0\WebDev.WebServer.EXE; параметры передаются через командую строку, например: /port:3840 /path:"С:\Projects\Site" /vpath:"/".
Сам веб-сервер - это класс Microsoft.VisualStudio.WebHost.Server, который помещен в GAC (WebDev.WebHost.dll).
Путь к файлу можно выяснить с помощью Process Monitor'а (см. Sysinternals Process Utilities). Открыть файл в проводнике не получится, но можно его предварительно скопировать с помощью copy в Command Prompt.

Тестируем работу клиента web-сервера

суббота, 18 апреля 2009 г.,

Протестировать работу клиента веб-сервера можно без самого веб-сервера. Достаточно установить Fiddler (см. Install Fiddler2) - это прокси с AutoResponder'ом. Автором Fiddler'а является Eric Lawrence - сотрудник Microsoft.
Предположим, что по адресу http://getvaluetest.ru расположен сайт, который на любой запрос присылает следующий http-ответ:
HTTP/1.1 200 OK
Date: Thu, 16 Apr 2009 08:39:02 GMT
Set-Cookie: name1=5; expires=Tue, 13-Apr-2010, 23:43:04, GMT; path=/; domain=.getvaluetest.ru
Set-Cookie: name2=5; expires=Tue, 13-Apr-2010, 23:43:04, GMT; path=/; domain=.getvaluetest.ru
Content-Length: 6
Content-Type: text/html; charset=windows-1251

привет
Сайта не существует, поэтому надо сохранить http-ответ в текстовый файл, например, c:\temp\200.txt, запустить Fiddler, в правой панели стать на AutoResponder и нажать кнопку Add. В левом поле Rule Editor указать http://GetValueTest.ru, а в правом поле - c:\temp\200.txt, нажать Save.
В приложение надо добавить слудующий код:
HttpResponse hr = new HttpResponse();
// запросить через прокси (Fiddler, который на IP: 127.0.0.1 "слушает" порт 8888)
hr.LoadFrom("http://getvaluetest.ru", new WebProxy(IPAddress.Loopback.ToString(), 8888));
System.Diagnostics.Trace.WriteLine(hr.Trace());
Ниже приводятся класс HttpResponse и его методы расширения:
public class HttpResponse
{
    public NameValueCollection Headers { get; set; }
    public string Contnet { get; set; }
    public Exception Error { get; set; }
}

public static class HttpResponseHelper
{
    public static void LoadFrom(this HttpResponse res, string url, WebProxy proxy)
    {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
        req.Proxy = proxy;
        req.Method = WebRequestMethods.Http.Get;
        try
        {
            using (HttpWebResponse wres = (HttpWebResponse)req.GetResponse())
            {
                if (req.HaveResponse)
                {
                    // если в http-ответе не указан charset, то получим: ISO-8859-1
                    var encoding = Encoding.GetEncoding(wres.CharacterSet);
                    using (StreamReader sr = new StreamReader(wres.GetResponseStream(), encoding))
                        res.Contnet = sr.ReadToEnd();

                    // копируем, потому что HttpWebResponse.Headers.GetValues(string)
                    // учитывает запятые в значении "Set-Cookie".
                    res.Headers = new NameValueCollection(wres.Headers);
                }
            }
        }
        catch (Exception exc)
        {
            res.Error = exc;
        }
    }

    public static string Trace(this HttpResponse hr)
    {
        if (hr.Error != null)
            return hr.Error.ToString();

        StringBuilder sb = new StringBuilder();
        foreach (string key in hr.Headers.AllKeys)
        {
            foreach (string value in hr.Headers.GetValues(key))
                sb.Append(key).Append(": ").Append(value).Append(Environment.NewLine);
        }
        sb.Append(Environment.NewLine);
        sb.Append(hr.Contnet);
        return sb.ToString();
    }
}

Вызов DomainService с веб-страницы

четверг, 9 апреля 2009 г.,

Класс DomainService входит в состав .NET RIA Services и используется в качестве базового, для классов, обменивающихся данными с Silverlight-приложениями. Но данные можно передавать и получать также с помощью XMLHttpRequest.
  1. Создать проект: ASP.NET Web Application
  2. Добавить в References: System.Web.Ria и System.Web.DomainServices
  3. Добавить в проект файл Class1.cs (см. ниже)
  4. В Web.config в httpHandlers добавить:
    <add path="DataService.axd" verb="GET,POST" type="System.Web.Ria.DataServiceFactory, System.Web.Ria, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
  5. В Default.aspx заменить содержимое (см. ниже)
  6. Запустить приложение. В IE откроется веб-страница с двумя кнопками Operation1 и Operation2. В результате нажатия на кнопку будет создан POST запрос, который попадет в соответствующий метод в классе Test.
    Результат запроса возвращается в JSON-формате:
    {"__type":"DataServiceResult:DomainServices", "IsDomainServiceException":false, "ReturnValue":"Hello 123"}

[Class1.cs]
using System.Web.DomainServices;
using System.Web.Ria;
using System;

namespace Cognitex.Web
{
    [EnableClientAccess]
    public class Test : DomainService
    {
        [ServiceOperation]
        public string Operation1()
        {
            return "Ticks: " + DateTime.Now.Ticks;
        }

        [ServiceOperation]
        public string Operation2(string value)
        {
            return "Hello " + value;
        }
    }
}

[Default.aspx]
<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>

    <script language="javascript" type="text/javascript">
        function Operation1() {
            var r = new XMLHttpRequest();
            r.open("POST", "/DataService.axd/Cognitex-Web-Test/Operation1", false);
            r.setRequestHeader("Content-Type", "text/json");
            r.send("[]");
            return r;
        }
        function Operation2(value) {
            var r = new XMLHttpRequest();
            r.open("POST", "/DataService.axd/Cognitex-Web-Test/Operation2", false);
            r.setRequestHeader("Content-Type", "text/json");
            r.send("[\"" + value + "\"]");
            return r;
        }
        function Trace(r) {
            var str = "";
            for (var o in r) str += o + ": " + r[o] + "<br/>";
            _Msg.innerHTML = str + "<hr/>" + eval("res=" + r.responseText).ReturnValue;
        }
    </script>

</head>
<body>
    <button onclick="Trace(Operation1())">Operation1</button>
    <br />
    <input id="_Data" value="123" /><button onclick="Trace(Operation2(_Data.value))">Operation2</button>
    <div id="_Msg" style="margin-top: 50px" />
</body>
</html>


Чтобы вызвать DomainService из Fiddler'а: 1) открыть закладку Request Builder 2) в выпадающем списке выбрать POST 3) указать адрес метода, например, http://ipv4.fiddler:5966/DataService.axd/Services-Test/Operation1 4) в поле Request Headers указать Content-Type: text/json 5) в поле Request Body указать [] 6) нажать Execute.
Для вызова метода Operation2 в поле Request Body надо указать, например, ["wow"]