FPHttpClient 404

Alle Fragen zur Netzwerkkommunikation
Antworten
Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

FPHttpClient 404

Beitrag von Warf »

Hey ho Leute,

ich stehe grade vor einem kleinen Problemchen, undswar habe ich eine Klasse um die FPHttpClient Klasse rumgebaut welche vernünftig Cookies implementiert, diese Klasse erstellt eine Instanz von FPHttpClient beim aufruf des Konstruktors, und die Get Methode sieht wie folgt aus

Code: Alles auswählen

 
Const
  SetCookie = 'set-cookie';
var
  i: integer;
  s: ansistring;
begin
  Http.RequestHeaders.Clear;
  if FUserAgent <> '' then
    Http.AddHeader('User-Agent', FUserAgent);
  // Set Cookies
  Cookies.WriteToStrings(Http.Cookies);
  // Perform Get
  Http.Get(AUrl, Response);
  // Get new cookies
  FCookies.Clear;
  for i := 0 to Http.ResponseHeaders.Count - 1 do
  begin
    s := Http.ResponseHeaders[i];
    If (LowerCase(Copy(s, 1, Length(SetCookie))) = SetCookie) Then
    begin
      System.Delete(s, 1, Pos(':', s));
      FCookies.Add(StrToCookie(s));
    end;
  end;


Nun bekomme ich allerdings nach den ersten 1-2 Requests ein 404 gesendet, obwohl diese Links tatsächlich exsistieren, und ich sie via:

Code: Alles auswählen

str := TFPHttClient.SimpleGet(Url);

auch bekommen kann.

Woran liegt das? Vielleicht daran dass ich das FPHttpClient Objekt wiederverwende und vergesse alles zu clearen oder kann das an was anderes liegen?
Oder habe ich etwas mit den Cookies vielleicht falsch gemacht?

Das hier ist die Prozedure Cookies.WriteToStrings:

Code: Alles auswählen

procedure TCookieJar.WriteToStrings(str: TStrings);
var
  i: integer;
begin
  str.BeginUpdate;
  try
    str.Clear;
    for i := 0 to Count - 1 do
    begin
      str.Add(Format('%s=%s', [Cookie[i].Name, Cookie[i].Value]));
      if Cookie[i].Expires <> 0 then
        str.Add(Format('%s=%s', [SExpires,
          DateTimeToRFC1123(Cookie[i].Expires)]));
      if Cookie[i].MaxAge > 0 then
        str.Add(Format('%s=%s', [SMaxAge, IntToStr(Cookie[i].MaxAge)]));
      if Length(Cookie[i].Domain) > 0 then
        str.Add(Format('%s=%s', [SDomain, Cookie[i].Domain]));
      if Length(Cookie[i].Path) > 0 then
        str.Add(Format('%s=%s', [SPath, Cookie[i].Path]));
      if Cookie[i].Secure then
        str.Add(SSecure);
      if Cookie[i].HttpOnly then
        str.Add(SHttpOnly);
      if not(Cookie[i].Extension in [#00 .. #31, #127]) then
        str.Add(Cookie[i].Extension);
    end;
  finally
    str.EndUpdate;
  end;
end;             

Und das StrToCookie

Code: Alles auswählen

 
function StrToCookie(s: ansistring): TCookie;
 
  function SplitPair(s: ansistring): TStringPair;
  begin
    Result := Pair(Copy(s, 1, Pos('=', s) - 1), Copy(s, Pos('=', s) + 1,
      Length(s) - Pos('=', s)));
  end;
 
var
  str: TStringList;
  P: TStringPair;
  i: integer;
begin
  str := TStringList.Create;
  try
    str.StrictDelimiter := True;
    str.Delimiter := ';';
    str.DelimitedText := s;
    P := SplitPair(str[0]);
    Result.Name := P[0];
    Result.Value := P[1];
    for i := 1 to str.Count - 1 do
    begin
      P := SplitPair(str[i]);
      if (Length(P[0]) = 0) and (LowerCase(P[1]) = LowerCase(SHttpOnly)) then
      begin
        Result.HttpOnly := True;
      end
      else if (Length(P[0]) = 0) and (LowerCase(P[1]) = LowerCase(SSecure)) then
      begin
        Result.Secure := True;
      end
      else if LowerCase(P[0]) = LowerCase(SExpires) then
      begin
        Result.Expires := RFC1123ToDateTime(P[1]);
      end
      else if LowerCase(P[0]) = LowerCase(SMaxAge) then
      begin
        Result.MaxAge := StrToInt(P[1]);
      end
      else if LowerCase(P[0]) = LowerCase(SDomain) then
      begin
        Result.Domain := P[1];
      end
      else if LowerCase(P[0]) = LowerCase(SPath) then
      begin
        Result.Path := P[1];
      end
      else if (Length(P[0]) = 1) and not(P[0][1] in [#00 .. #31, #127]) then
      begin
        Result.Extension := P[0][1];
      end;
    end;
  finally
    str.Free;
  end;
end;   

Antworten