Преобразование необработанного HTTP-запроса в объект HTTPWebRequest - PullRequest
22 голосов
/ 25 ноября 2008

В .NET возможно ли преобразовать необработанный HTTP-запрос в объект HTTPWebRequest?

Я уверен, что .NET внутренне это делает. Любая идея, какая часть .NET на самом деле обрабатывает это? Могу ли я назвать это или есть какая-нибудь внешняя библиотека, которая позволяет необработанные HTTP-соединения?

Ответы [ 3 ]

9 голосов
/ 10 февраля 2009

Я не верю, что существует открытый метод для этого. Возможно, вам придется найти или написать синтаксический анализатор, чтобы разбить запрос, а затем написать собственный класс, расширяющий HttpWebRequest.

Вот что выглядит как парсер из CodeProject:

http://www.codeproject.com/KB/IP/CSHTTPServer.aspx

Я посмотрел код ротора для HttpWebRequest (кратко) и не увидел ничего, что выделялось бы как серебряная пуля. Вот ссылка на файл:

http://www.123aspx.com/Rotor/RotorSrc.aspx?rot=40844

Весь код ротора здесь для просмотра онлайн:

http://www.123aspx.com/Rotor/default.aspx

И здесь вы можете скачать его:

http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-AE17-3121B4F51D4D&displaylang=en

Я знаю, что куча ссылок на самом деле не отвечает на ваш вопрос, но я не думаю, что функциональность, которую вы ищете, представлена ​​в платформе. Мне бы очень хотелось оказаться ошибочным, поэтому, пожалуйста, обновите пост, если вы найдете хороший способ сделать это. Я знаю, что инструменты должны это делать, все, что написано в .Net, которое регистрирует необработанные запросы и затем позволяет вам повторять их, делает что-то подобное. Я считаю, что fiddler (http://www.fiddler2.com) написано в .Net, вы можете отправить электронное письмо этим парням и посмотреть, могут ли они помочь.

2 голосов
/ 07 января 2019

Теперь это возможно, но только с .Net Core 2.0+. Используйте Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser class:

using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Text;

public class Program : IHttpRequestLineHandler, IHttpHeadersHandler
{
    public static void Main(string[] args)
    {
        string requestString =
@"POST /resource/?query_id=0 HTTP/1.1
Host: example.com
User-Agent: custom
Accept: */*
Connection: close
Content-Length: 20
Content-Type: application/json

{""key1"":1, ""key2"":2}";
        byte[] requestRaw = Encoding.UTF8.GetBytes(requestString);
        ReadOnlySequence<byte> buffer = new ReadOnlySequence<byte>(requestRaw);
        HttpParser<Program> parser = new HttpParser<Program>();
        Program app = new Program();
        Console.WriteLine("Start line:");
        parser.ParseRequestLine(app, buffer, out var consumed, out var examined);
        buffer = buffer.Slice(consumed);
        Console.WriteLine("Headers:");
        parser.ParseHeaders(app, buffer, out consumed, out examined, out var b);
        buffer = buffer.Slice(consumed);
        string body = Encoding.UTF8.GetString(buffer.ToArray());
        Dictionary<string, int> bodyObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, int>>(body);
        Console.WriteLine("Body:");
        foreach (var item in bodyObject)
            Console.WriteLine($"key: {item.Key}, value: {item.Value}");
        Console.ReadKey();
    }

    public void OnHeader(Span<byte> name, Span<byte> value)
    {
        Console.WriteLine($"{Encoding.UTF8.GetString(name)}: {Encoding.UTF8.GetString(value)}");
    }

    public void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
    {
        Console.WriteLine($"method: {method}");
        Console.WriteLine($"version: {version}");
        Console.WriteLine($"target: {Encoding.UTF8.GetString(target)}");
        Console.WriteLine($"path: {Encoding.UTF8.GetString(path)}");
        Console.WriteLine($"query: {Encoding.UTF8.GetString(query)}");
        Console.WriteLine($"customMethod: {Encoding.UTF8.GetString(customMethod)}");
        Console.WriteLine($"pathEncoded: {pathEncoded}");
    }
}

Выход:

Start line:
method: Post
version: Http11
target: /resource/?query_id=0
path: /resource/
query: ?query_id=0
customMethod:
pathEncoded: False
Headers:
Host: example.com
User-Agent: custom
Accept: */*
Connection: close
Content-Length: 20
Content-Type: application/json
Body:
key: key1, value: 1
key: key2, value: 2
1 голос
/ 07 апреля 2009

Google для Cassinni, который был HTTP-сервером с источником, изначально предложенным Microsoft, который мог принимать вызовы ASP.NET. Вы должны разобрать запрос самостоятельно и загрузить его, но Cassinni будет хорошей отправной точкой. Этот URL может помочь:

http://blogs.msdn.com/dmitryr/archive/2005/09/27/474534.aspx

...