HTTP и сокеты в free pascal
Добавлено: 22.06.2014 11:56:27
Здравствуйте.
Пишу генератор и анализатор http-запросов, используя модуль sockets (без синапсов, инди и прочего).
Пока не вышел даже генератор
Гуглы не особо помогли. В основном опирался на справку.
Lazarus 1.2.0, Windows.
Опишу всё по порядку. Во-первых, вот мой с горем созданный код.
Теперь вопросы
1. Самое печальное, что не один сервер ничего кроме 400 ошибки мне так и не вернул (а иные и вовсе виснут\не отвечают, как тут сделать таймаут ответа - пока не понял). Что я пишу не так в запросе? Вроде все переносы и пустая строка имеются. Может, с символами (#10 #13) что не так?
2. Не могу понять, как и где считать заголовки ответа? fprecv выдает лишь тело.
3. Как правильно считать при помощи всё той же fprecv весь ответ сразу? Мой метод с считыванием порциями (в коде черновой пример, лишь две "порции") явно кривой и нехороший.
Пока только такие вопросы. Но без их решения двигаться дальше у меня и не выйдет.
Очень надеюсь на советы и помощь
Пишу генератор и анализатор http-запросов, используя модуль sockets (без синапсов, инди и прочего).
Пока не вышел даже генератор
Гуглы не особо помогли. В основном опирался на справку.
Lazarus 1.2.0, Windows.
Опишу всё по порядку. Во-первых, вот мой с горем созданный код.
- Код: Выделить всё
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
Sockets, resolve;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Memo1: TMemo;
Memo2: TMemo;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
Sock, rc:Tsocket;
sAddr : TSockAddr;
sin, sout : Text;
Line,dom : String;
msg:string;
rec:array[0..300] of char;//string;
i:integer;
hrs: THostResolver;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
dom:=Edit1.Text;
hrs:= THostResolver.Create(nil);
hrs.NameLookup(dom);
with sAddr do
begin
sin_family := AF_INET; //TCP\IP
sin_port:= htons(80); //Порт
sin_addr:=StrToNetAddr(hrs.AddressAsString);
end;
Sock:=fpsocket(AF_INET, SOCK_STREAM, 0); //создание сокета: стек протоколов TCP\IP, Потоковый, TCP(по умолчанию)
ShowMessage('SOCK '+ IntToStr(sock)); //эти шоумесседжи для проверки создания\выполнения операции
rc:=fpconnect(Sock, @sAddr, sizeof(sAddr)); //Соединение сокета с адресом sAddr
ShowMessage('CONNECT '+ IntToStr(rc));
//сообщение для отправки. Исходные данные взяты из FireFox 30
msg := 'GET http://'+dom+'/ HTTP/1.1'+#13+#10+ // пробовал и "/" просто вместо адреса сайта целиком
'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0'+#13+#10+
'Host: '+dom+#13+#10+
'DNT: 1'+#13+#10+
'Connection: keep-alive'+#13+#10+
'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3'+#13+#10+
'Accept-Encoding: gzip, deflate'+#13+#10+
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'+#13+#10+
#13+#10;
// Пробовал и просто одну строку типа "GET <домен> HTTP/1.1" (+пустая строка)
Memo2.Clear;
Memo2.Lines.Add(msg); //на всякий случай, дабы проверить все переносы и т.п.
rc:=fpsend(sock, @msg, sizeof(msg), 0); //передача
ShowMessage('SEND '+ IntToStr(rc));
rc:=fprecv(sock, @rec, 72, 0); // приём ответной страницы
ShowMessage('RECV '+ IntToStr(rc));
Memo1.Lines.Add(rec);
rc:=fprecv(sock, @rec+72, 108, 0); // приём ответной страницы , след.порция
ShowMessage('RECV '+ IntToStr(rc));
Memo1.Lines.Add(rec);
Memo1.Clear;
Memo1.Lines.Add(rec);
CloseSocket(sock);
FreeAndNil(hrs);
end;
end.
Теперь вопросы
1. Самое печальное, что не один сервер ничего кроме 400 ошибки мне так и не вернул (а иные и вовсе виснут\не отвечают, как тут сделать таймаут ответа - пока не понял). Что я пишу не так в запросе? Вроде все переносы и пустая строка имеются. Может, с символами (#10 #13) что не так?
2. Не могу понять, как и где считать заголовки ответа? fprecv выдает лишь тело.
3. Как правильно считать при помощи всё той же fprecv весь ответ сразу? Мой метод с считыванием порциями (в коде черновой пример, лишь две "порции") явно кривой и нехороший.
Пока только такие вопросы. Но без их решения двигаться дальше у меня и не выйдет.
Очень надеюсь на советы и помощь