Search code examples
delphiapidelphi-7indyblogger

blogger via idHTTP : error 400 bad request


I'm trying to post to Blogger using idHTTP component, however, I'm getting "HTTP/1.0 400 Bad Request" error.

procedure TForm1.Button1Click(Sender: TObject);
var request,response,req  : TStringlist;
    auth,blogid : string;
begin
blogid    := '00000000000000000000000';
request   := TStringList.Create;
response  := TStringList.Create;
req       := TStringList.Create;

IdHTTP1.Request.Connection := 'Keep-Alive';
IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;

request.Clear();
request.Values['accountType'] := 'GOOGLE';
request.Values['Email']       := '[email protected]';
request.Values['Passwd']      := 'yyy';
request.Values['service']     := 'blogger';

response.Text :=IdHTTP1.Post('https://www.google.com/accounts/ClientLogin',request);
auth := response.Values['Auth'];  //working perfectly

req.Clear();
req.Text := Memo2.Lines.Text;  //put entry into request var

IdHTTP1.Request.CustomHeaders.Clear();
IdHTTP1.Request.CustomHeaders.Add('GData-Version: 2');
//IdHTTP1.Request.CustomHeaders.Add('Authorization: GoogleLogin auth='+auth);
IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'GoogleLogin auth = '+auth;
IdHTTP1.Request.ContentType := 'application/atom+xml';

memo1.Text := IdHTTP1.Post('https://www.blogger.com/feeds/' + blogid + '/posts/default', req); // I got "HTTP/1.0 400 Bad Request" error right here.

end;

gor error on

memo1.Text := IdHTTP1.Post('https://www.blogger.com/feeds/' + blogid + '/posts/default', req);

Does anyone know what I'm doing wrong?

Any help is greatly appreciated. Thank you!


Solution

  • You are posting your XML data using a TStringList. Even though you are not setting the Request.ContentType to application/x-www-form-urlencoded, posting a TStrings object will always encode the data as if you did. That is likely why the server is complaining, because it will not receieve your intended XML correctly. To post XML data, you need to use a TStream instead, eg:

    procedure TForm1.Button1Click(Sender: TObject);
    var
      request, response : TStringlist;
      req : TStream;
      auth, blogid : String;
    begin
      blogid := '00000000000000000000000';
    
      IdHTTP1.Request.Connection := 'Keep-Alive';
      IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;
    
      request := TStringList.Create;
      try
        response := TStringList.Create;
        try
          request.Values['accountType'] := 'GOOGLE';
          request.Values['Email']       := '[email protected]';
          request.Values['Passwd']      := 'yyy';
          request.Values['service']     := 'blogger';
    
          IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';
          response.Text := IdHTTP1.Post('https://www.google.com/accounts/ClientLogin', request);
    
          auth := response.Values['Auth'];
        finally
          response.Free;
        end;
      finally
        request.Free;
      end;
    
      req := TMemoryStream.Create;
      try
        Memo2.Lines.SaveToStream(req);
        req.Position := 0;
    
        IdHTTP1.Request.CustomHeaders.Clear;
        IdHTTP1.Request.CustomHeaders.Values['GData-Version'] := '2';
        IdHTTP1.Request.CustomHeaders.Values['Authorization'] := 'GoogleLogin auth = ' + auth;
        IdHTTP1.Request.ContentType := 'application/atom+xml';
    
        Memo1.Text := IdHTTP1.Post('https://www.blogger.com/feeds/' + blogid + '/posts/default', req);
      finally
        req.Free;
      end;
    end;