Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: REST>Google Contacts API>POST returns a bad request error (400)


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 9 - Last Post: Feb 17, 2017 4:29 AM Last Post By: ibrahim kazancı
Jean-Fabien Con...

Posts: 14
Registered: 9/8/01
REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 12, 2015 6:20 AM
I'm running Delphi XE5 (Update 2) and I'm coding against Google Contacts API, leveraging the REST components.
I've been able to authenticate against the API, leveraging OAuth2 authenticator.
I've been able to retrieve contacts by doing a GET request against the API.
I haven't been able to push data by doing a POST request against the API. I always receive a bad request error (400) from server with no additional useful detail in the response The POST request contains XML code in the body of the request.

Here's the code snippet (trying to create a Google Contacts Group here):

RESTClient.BaseURL := 'https://www.google.com/m8/feeds';
RESTClient.Authenticator := OAuth2_GoogleContacts;
RESTClient.ContentType := 'application/atom+xml';

RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.Resource := 'groups/default/full';

RESTRequest.Accept := 'application/atom+xml, application/json, text/plain; q=0.9, text/html;q=0.8,';
RESTRequest.Params.AddHeader('GData-Version', '3.0');

XMLText := '<?xml version="1.0" encoding="utf-8"?>' +
'<entry xmlns:gd="http://schemas.google.com/g/2005">' +
'<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#group" />' +
'<title type ="text">Foo</title>' +
'</entry>';

RESTRequest.AddBody(XMLText, ctAPPLICATION_ATOM_XML);

RESTRequest.Execute;

I've tried multiple things with adding XML to the body (using streams, forcing UTF8 encoding, etc.) of the request but always the same bad request error.
I've checked API scope, etc. and it all looks good. Also worth to note that sending the request through Google OAuth2 Playground works well.

Thanks in advance for any help with this.
Jean-Fabien Con...

Posts: 14
Registered: 9/8/01
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 23, 2015 5:24 AM   in response to: Jean-Fabien Con... in response to: Jean-Fabien Con...
Debugging with Fiddler4, it appears that the Content-Type of the XML part is NOT set to application/atom+xml but to text/plain like the access_token which is added automatically to the body by the REST framework.
Note that the Content-Type at the top level is set to multipart/form-data by the REST framework.
This may be the issue but not sure how to correct this yet. Also note the =3D string being present in the XML part which I guess is replacing the = char during encoding.

----------052315110120278
Content-Disposition: form-data; name="{ABE6AA81-0A51-4176-A2CE-9C77AF5528D3}"
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

<?xml version=3D"1.0" encoding=3D"utf-8"?><entry xmlns:gd=3D"http://sc=
hemas.google.com/g/2005"><category scheme=3D"http://schemas.google.com=
/g/2005#kind" term=3D"http://schemas.google.com/contact/2008#group" />=
<title type=3D"text">Foo</title></entry>
----------052315110120278
Content-Disposition: form-data; name="access_token"
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

ya29.fAFVl6nSHxEH3TWA9384A1jF49j5AxeJT5...
----------052315110120278--
Jean-Fabien Con...

Posts: 14
Registered: 9/8/01
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 26, 2015 1:13 AM   in response to: Jean-Fabien Con... in response to: Jean-Fabien Con...
May it be that this is an issue with Delphi XE5 which would have been fixed in a later release?
This post (http://stackoverflow.com/questions/24305816/) is outlining some XE5 and XE6 difference in results.
I browsed QualityCentral but didn't find any specific ticket outlining a change/fix in REST framework which could explain this.
Christopher Burke

Posts: 580
Registered: 9/25/99
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 26, 2015 6:01 AM   in response to: Jean-Fabien Con... in response to: Jean-Fabien Con...
Jean-Fabien Connault <> wrote in news:724824 at forums dot embarcadero dot com:

May it be that this is an issue with Delphi XE5 which would have been
fixed in a later release? This post
(http://stackoverflow.com/questions/24305816/) is outlining some XE5
and XE6 difference in results. I browsed QualityCentral but didn't
find any specific ticket outlining a change/fix in REST framework
which could explain this.

The issue is a windows (win32) error code that is returned from a win32
call.
Jean-Fabien Con...

Posts: 14
Registered: 9/8/01
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 26, 2015 2:39 PM   in response to: Christopher Burke in response to: Christopher Burke
The issue is a windows (win32) error code that is returned from a win32
call.

Thanks. Do you have specific/further details? Is there a workaround?
Jean-Fabien Con...

Posts: 14
Registered: 9/8/01
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 30, 2015 6:06 AM   in response to: Jean-Fabien Con... in response to: Jean-Fabien Con...
Here's a working workaround:

RESTClient.BaseURL := 'https://www.google.com/m8/feeds';
//RESTClient.Authenticator := OAuth2_GoogleContacts;
RESTClient.ContentType := 'application/atom+xml';

RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.Resource := 'groups/default/full';

RESTRequest.Accept := 'application/atom+xml';
RESTRequest.Params.AddHeader('GData-Version', '3.0');

XMLText := '<?xml version="1.0" encoding="utf-8"?>' +
'<entry xmlns:gd="http://schemas.google.com/g/2005">' +
'<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#group" />' +
'<title type="text">Foo</title>' +
'</entry>';

RESTRequest.Params.AddItem('Authorization', 'Bearer ' + OAuth2_GoogleContacts.AccessToken, TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
RESTRequest.AddBody(XMLText, ctAPPLICATION_ATOM_XML);

RESTRequest.Execute;

The key is to NOT set the Authenticator (commented in the above code) and to add manually the AccessToken as an Authorization header.
Jean-Fabien Con...

Posts: 14
Registered: 9/8/01
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 4, 2015 2:08 AM   in response to: Jean-Fabien Con... in response to: Jean-Fabien Con...
Not REST related but needed for proper UTF-8 encoding.

This line...

RESTRequest.AddBody(XMLText, ctAPPLICATION_ATOM_XML);

...should be replaced with...

RequestStringStream := TStringStream.Create(XMLText, TEncoding.UTF8);
RESTRequest.AddBody(RequestStringStream, TRESTContentType.ctAPPLICATION_ATOM_XML);
RequestStringStream.Free;
Jean-Fabien Con...

Posts: 14
Registered: 9/8/01
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 18, 2016 4:39 AM   in response to: Jean-Fabien Con... in response to: Jean-Fabien Con...
I just installed Delphi 10.1 Berlin and the "RESTRequest.Execute;" lines generated an exception. Looks like it doesn't like the use of StringStream with "RESTRequest.AddBody".
I've tried to use "RESTRequest.AddBody(XMLText, ctAPPLICATION_ATOM_XML);" again but it compains again about bad request error (400).
Looking at it, it seems that when RESTRequest.Execute happens, it adds the access_token string (from Google OAuth) as a parameter at the end of the body, causing the body XML string to be incorrect.
I haven't found a way to prevent the access_token string to be added at the end of the body. Any thoughts? Is it a bug with TREST in Delphi 10.1 Berlin?
Jean-Fabien Con...

Posts: 14
Registered: 9/8/01
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Sep 30, 2016 9:50 AM   in response to: Jean-Fabien Con... in response to: Jean-Fabien Con...
So with Delphi 10.1 Berlin, the authenticator had to be nil'ed explicitly and I went back using AddBody with a String parameter instead of a StringStream.

RESTClient.BaseURL := 'https://www.google.com/m8/feeds';
RESTClient.Authenticator := nil;
RESTClient.ContentType := 'application/atom+xml';

RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.Resource := 'groups/default/full';
RESTRequest.Accept := 'application/atom+xml';
RESTRequest.Params.AddHeader('GData-Version', '3.0');

XMLText := '<?xml version="1.0" encoding="utf-8"?>' +
'<entry xmlns:gd="http://schemas.google.com/g/2005">' +
'<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#group" />' +
'<title type="text">Foo</title>' +
'</entry>';

RESTRequest.Params.AddItem('Authorization', 'Bearer ' + OAuth2_GoogleContacts.AccessToken, TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
RESTRequest.AddBody(XMLText, TRESTContentType.ctAPPLICATION_ATOM_XML);

RESTRequest.Execute;
ibrahim kazancı

Posts: 1
Registered: 11/17/05
Re: REST>Google Contacts API>POST returns a bad request error (400)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 17, 2017 4:29 AM   in response to: Jean-Fabien Con... in response to: Jean-Fabien Con...
Jean-Fabien Connault wrote:
So with Delphi 10.1 Berlin, the authenticator had to be nil'ed explicitly and I went back using AddBody with a String parameter instead of a StringStream.

RESTClient.BaseURL := 'https://www.google.com/m8/feeds';
RESTClient.Authenticator := nil;
RESTClient.ContentType := 'application/atom+xml';

RESTRequest.Method := TRESTRequestMethod.rmPOST;
RESTRequest.Resource := 'groups/default/full';
RESTRequest.Accept := 'application/atom+xml';
RESTRequest.Params.AddHeader('GData-Version', '3.0');

XMLText := '<?xml version="1.0" encoding="utf-8"?>' +
'<entry xmlns:gd="http://schemas.google.com/g/2005">' +
'<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#group" />' +
'<title type="text">Foo</title>' +
'</entry>';

RESTRequest.Params.AddItem('Authorization', 'Bearer ' + OAuth2_GoogleContacts.AccessToken, TRESTRequestParameterKind.pkHTTPHEADER, [poDoNotEncode]);
RESTRequest.AddBody(XMLText, TRESTContentType.ctAPPLICATION_ATOM_XML);

RESTRequest.Execute;

Thanks for this valuable information for 10.1 Berlin.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02