HTTP и сокеты в free pascal
 Добавлено: 22.06.2014 11:56:27
Добавлено: 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 весь ответ сразу? Мой метод с считыванием порциями (в коде черновой пример, лишь две "порции") явно кривой и нехороший.
Пока только такие вопросы. Но без их решения двигаться дальше у меня и не выйдет.
Очень надеюсь на советы и помощь

 Спасибо за подтверждение.
 Спасибо за подтверждение.