думал увижу велик о редиректе , а увидел
Его нетрудно эмулировать - парсингом первичного ответа и повторным вызовом по результатам парсинга.
Добавлено спустя 24 минуты 27 секунд:Можно даже дописать синапсовый HTTPMethod :
http://www.webdelphi.ru/2010/10/class-helper-dlya-synapse/Здесь мы вначале перед отправкой данных на сервер сохраняем значения Cookies, Headers и Document для того, чтобы в случае наличия редиректа не потерять эти данные (они автоматически заменяться на заголовки, куки и html-код перенаправления соответственно). Затем отправляем данные с использованием «родного» HTTPMethod и анализируем результат. Если получили код перенаправления, то определяем значение заголовка location и снова отправляем запрос.
Для бОльшей универсальности необходимо было бы сделать подсчёт редиректов и перенаправлять до тех пор пока не получим код отличный от 3хх, но мне такая универсальность не нужна, а Вы сможете дописать метод в любой момент.
- Код: Выделить всё
type
THTTPSend_ = class helper for THTTPSend
public
function HeaderNameByIndex(index:integer):string;
function HeaderByName(const HeaderName:string):string;
end;
function THTTPSend_.HeaderNameByIndex(index: integer): string;
begin
if (index>(Headers.Count-1))or(index<0) then Exit;
Result:=copy(Headers[index],0, pos(':',Headers[index])-1)
end;
function THTTPSend_.HeaderByName(const HeaderName: string): string;
var i:integer;
begin
for i:=0 to Headers.Count-1 do
begin
if LowerCase(HeaderNameByIndex(i))=lowercase(HeaderName) then
begin
Result:=copy(Headers[i],pos(':',
LowerCase(Headers[i]))+2,
Length(Headers[i])-length(HeaderName));
break;
end;
end;
end;
function THTTPSend_.HTTPMethod(const Method, URL: string): Boolean;
var Heads: TStringList;
Cooks: TStringList;
Redirect: string;
Doc:TMemoryStream;
begin
try
Heads:=TStringList.Create;
Cooks:=TStringList.Create;
Doc:=TMemoryStream.Create;
Doc.LoadFromStream(Document);
Cooks.Assign(Cookies);
Heads.Assign(Headers);
Result:=inherited HTTPMethod(Method,URL);
if (ResultCode=301)or(ResultCode=302) then
begin
Redirect:=HeaderByName('location');
Headers.Assign(Heads);
Document.Clear;
Document.LoadFromStream(Doc);
Cookies.Assign(Cooks);
Result:=inherited HTTPMethod(Method,Redirect);
end;
finally
FreeAndNil(Heads);
FreeAndNil(Cooks);
FreeAndNil(Doc)
end;
end;
var HTTP: THTTPSend;
begin
try
HTTP:=THTTPSend.Create;
if HTTP.HTTPMethod('GET','AnyURL') then
begin
Memo1.Lines.Add('-----------------------------');
Memo1.Lines.Add(HTTP.Headers.Text);
Memo1.Lines.Add('-----------------------------');
end
Indy - для продвинутых, Synapse - для ленивых

Вот еще вариант с расширением класса HTTPSend (подходит для ФПЦ, так как не нуждается в HELPER-классах):
- Код: Выделить всё
{Unit: IngHTTPSend}
{Author: Pikhovkin S.}
{E-mail: pikhovkins@gmail.com}
unit IngHTTPSend;
interface
uses
Classes, SysUtils, HTTPSend, ZLibExGZ, SSL_OpenSSL;
type
{ TIngHTTPSend }
TIngHTTPSend = class(THTTPSend)
private
fGZIPDecode: Boolean;
fOutStream: TMemoryStream;
function GetDefaultHeader: String;
procedure SetGZIPDecode(Value: Boolean);
protected
public
constructor Create;
destructor Destroy; override;
function SendHTTP(const ToHeader, ToURL, ToDocument: string): Integer;
function GetParamValue(const PosParam: String; const PosValue: String = ''): String;
function URLDecode(const Value: String): String;
function URLEncode(const Value: String): String;
function HTTPEncode(const Value: String): String;
published
property Headers;
property Cookies;
property Document;
property MimeType;
property Protocol;
property KeepAlive;
property Status100;
property ProxyHost;
property ProxyPort;
property ProxyUser;
property ProxyPass;
property UserAgent;
property ResultCode;
property ResultString;
//-------------------
property DefaultHeader: String read GetDefaultHeader;
property GZIPDecode: Boolean write SetGZIPDecode default true;
end;
implementation
{ TIngHTTPSend }
constructor TIngHTTPSend.Create;
begin
inherited;
fOutStream := TMemoryStream.Create;
fGZIPDecode := true;
fProtocol := '1.1';
fUserAgent := 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)';
end;
destructor TIngHTTPSend.Destroy;
begin
fOutStream.Free;
inherited;
end;
function TIngHTTPSend.GetDefaultHeader: String;
begin
Result := 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' + #13#10 +
'Accept-Language: ru,en-us;q=0.7,en;q=0.3' + #13#10 +
'Accept-Encoding: gzip,deflate' + #13#10 +
'Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7';
end;
function TIngHTTPSend.GetParamValue(const PosParam: String; const PosValue: String = ''): String;
var
PosList: TStringList;
begin
Result := '';
PosList := TStringList.Create;
try
PosList.Assign(Headers);
PosList.NameValueSeparator := ':';
if PosValue = '' then
Result := Trim(PosList.Values[PosParam]) else
if Pos(PosValue, PosList.Values[PosParam]) > 0
then Result := PosValue;
finally
PosList.Free;
end;
end;
function TIngHTTPSend.SendHTTP(const ToHeader, ToURL, ToDocument: string): Integer;
var
HttpMethodKind: String;
SL: TStringList;
begin
HttpMethodKind := 'GET';
Headers.Clear;
Document.Clear;
if ToHeader = '' then
Headers.Add(DefaultHeader) else
Headers.Add(ToHeader);
MimeType := '';
if ToDocument <> '' then
begin
HttpMethodKind := 'POST';
MimeType := 'application/x-www-form-urlencoded';
Document.Write(PChar(ToDocument)^, Length(ToDocument));
end;
HTTPMethod(HttpMethodKind, ToURL);
Result := ResultCode;
if {(Document.Size > 0) and} (ResultCode = 200) then
if fGZIPDecode then
if (GetParamValue('Content-Encoding', 'gzip') = 'gzip') and ((GetParamValue('Content-Type', 'text/') = 'text/') or (Pos('https://', ToURL) = 1)) then
begin
try
GZDecompressStream(Document, fOutStream);
Document.LoadFromStream(fOutStream);
Document.Position := 0;
fOutStream.Clear;
except
Result := 0;
Document.SaveToFile('error_Decomp_' + FormatDateTime('hh-nn-ss-zzz', Time)+'.html');
Document.Clear;
SL := TStringList.Create;
SL.Add('Result = ' + IntToStr(ResultCode) + ' ' + ResultString);
SL.Add(ToURL);
SL.Add(ToDocument);
SL.SaveToFile('error_Decomp_' + FormatDateTime('hh-nn-ss-zzz', Time)+'.log');
SL.Free;
end;
end;
end;
procedure TIngHTTPSend.SetGZIPDecode(Value: Boolean);
begin
fGZIPDecode := Value;
end;
function TIngHTTPSend.URLDecode(const Value: String): String;
var
Sp, Rp, Cp, Tp: PChar;
int: Integer;
S: String;
begin
SetLength(Result, Length(Value));
Sp := PChar(Value);
Rp := PChar(Result);
while Sp^ <> #0 do
begin
case Sp^ of
'+': Rp^ := ' ';
'%':
begin
Tp := Sp;
Inc(Sp);
if Sp^ = '%' then
Rp^ := '%' else
begin
Cp := Sp;
Inc(Sp);
if (Cp^ <> #0) and (Sp^ <> #0) then
begin
S := '$' + Cp^ + Sp^;
if TryStrToInt(s, int) then
Rp^ := Chr(int)
else
begin
Rp^ := '%';
Sp := Tp;
end;
end
else
begin
Rp^ := '%';
Sp := Tp;
end;
end;
end; // '%':
else Rp^ := Sp^;
end; // case of
Inc(Rp);
Inc(Sp);
end; // while Sp^ <> #0 do
SetLength(Result, Rp - PChar(Result));
end;
function TIngHTTPSend.URLEncode(const Value: String): String;
const
NoConversion =
['A'..'Z', 'a'..'z', '*', '@', '.', '_', '-', '0'..'9', '$', '!', '''', '(', ')'];
var
Sp, Rp: PChar;
begin
SetLength(Result, Length(Value) * 3);
Sp := PChar(Value);
Rp := PChar(Result);
while Sp^ <> #0 do
begin
if Sp^ in NoConversion then
Rp^ := Sp^ else
begin
FormatBuf(Rp^, 3, '%%%.2x', 6, [Ord(Sp^)]);
Inc(Rp,2);
end;
Inc(Rp);
Inc(Sp);
end;
SetLength(Result, Rp - PChar(Result));
end;
function TIngHTTPSend.HTTPEncode(const Value: String): String;
var
vI, vN: Integer;
vStr, S: String;
vSLDest: TStringList;
P: PChar;
begin
if (Pos('http', Value) = 1) and (Pos('?', Value) > 0) then
begin
vStr := Value;
Result := Copy(vStr, 1, Pos('?', vStr));
Delete(vStr, 1, Pos('?', vStr));
vSLDest := TStringList.Create;
try
S := '';
P := PChar(vStr);
while P^ <> #0 do
begin
if P^ <> '&' then
S := S + P^ else
begin
vSLDest.Add(S);
S := '';
end;
//{$IFDEF MSWINDOWS} P := CharNext(P); {$ELSE}
Inc(P);
//{$ENDIF}
end;
if vStr <> '' then
vSLDest.Add(S);
vN := vSLDest.Count - 1;
for vI := 0 to vN do
begin
vSLDest.ValueFromIndex[vI] := URLEncode(vSLDest.ValueFromIndex[vI]);
Result := Result + vSLDest.Strings[vI];
if vi < vN then
Result := Result + '&';
end;
finally
vSLDest.Free;
end;
end else
Result := URLEncode(Value);
end;
end.
Добавлено спустя 16 минут 59 секунд:В принципе, человек пишет пргу для общения с корпоративным сайтом - там редирект не нужен.