What's wrong with this OData batch update query? - odata

I followed the example from here but I cannot get this to work!
I can't see anything wrong with the update query and I can't think of what to change because it seems fine. I'm only testing with one request because I wanted to make sure it works first.
Here's the request's body:
--batch_hJUuHcmH7ADWhYbtkF0o9JWlq
Content-Type: multipart/mixed; boundary=changeset_oYIVi6ByvAtKBlI7hqFWoOwX7
--changeset(oYIVi6ByvAtKBlI7hqFWoOwX7)
Content-Type: application/http
Content-Transfer-Encoding: binary
MERGE PrescriptionService.svc/Prescriptions(1L) HTTP/1.1
Host: 192.168.10.179
Content-Type: application/json;odata=verbose
{"PrescriptionType":"RegularMedicationPrescriptionType","Page":"0","Comment":"whoaaaaaa"}
--changeset(oYIVi6ByvAtKBlI7hqFWoOwX7)--
--batch(hJUuHcmH7ADWhYbtkF0o9JWlq)--
I get a 202 Accepted so the "overall" batch request is not malformed. This is the response from the server:
--batchresponse_d8e813eb-0327-4518-9312-9b7a55d0da0c
Content-Type: multipart/mixed; boundary=changesetresponse_fc085e3b-68a8-46dd-86c6-334b1070607d
--changesetresponse_fc085e3b-68a8-46dd-86c6-334b1070607d--
--batchresponse_d8e813eb-0327-4518-9312-9b7a55d0da0c--
I tried POSTing to that same URL in the batch body to create an entity and it doesn't work either, so it has to be something with the request body.
What's wrong with the request's body?

The changeset boundary as specified in the header:
boundary=changeset_oYIVi6ByvAtKBlI7hqFWoOwX7
must match exactly the one used later on:
--changeset(oYIVi6ByvAtKBlI7hqFWoOwX7)
Which it doesn't. I don't know why you added the parenthesis, but they should not be there.
Same goes for the batch boundary itself.

Related

Delphi 10 TRestClient MIME boundary issue

I am trying to consume a REST service using TRestClient but I believe there is an issue with the boundary string for multipart content.
I am capturing the body of the request I am sending, and this is the content type header:
Content-Type: multipart/form-data; boundary=-------Embt-Boundary--07CC944C29DA577E
Then, this is the first section of the multipart form:
-----------Embt-Boundary--07CC944C29DA577E
Content-Disposition: form-data; name="file"; filename="ce.csv"
Content-Type: text/csv
And this is how it ends:
---------Embt-Boundary--07CC944C29DA577E--
I don't think this is an issue on the server, as even my proxy is not able to parse the body:
When I compare this same request vs postman, I notice that the starting and ending boundaries do not match!
Starting: -----------Embt-Boundary--07CC944C29DA577E
Ending: ---------Embt-Boundary--07CC944C29DA577E--
I found that the boundary generation is done in TMultipartFormData.GenerateBoundary() from System.Net.Mime:
When checking the starting and ending boundaries from postman, they match, so I am almost sure this is the issue. I don't think it is related to my code, but let me know if you need it.

Server App on Heroku is not accessibe

Hi we have a Ruby on Rails server application on Heroku, but when I send a post request to it, I always get a 400 Bad Request response. I have searched other 400 errors, but none are related to our issue. The HTTP response that we receive looks like this below:
HTTP/1.1 400 Bad Request
Server: Cowboy
Date: Fri, 14 Aug 2015 21:55:25 GMT
Content-Length: 0
The post request that I am sending looks like this below:
POST http://ourapp.herokuapp.com/api/v1/requests HTTP/1.0
Accept-Language: en-us
Accept: text/plain
Content-Type: application/x-www-form-urlencoded
Content-Length: 38
Connection: Close
request=600&key=&newKey=danasecretkey&
Sorry, I had to put blank lines after each header or it would all show up on one line.
If I create an HTML form to send the data, there is no issue. It's when I then try to send the same request from our file server, that I get the errors. I tried using a preflight request with all of the correct request headings, but received the same 400 Bad Request error.
Does anyone have any suggestions as to what I might be doing wrong?
Well, just guessing from what you've said:
request=600&key=&newKey=danasecretkey&
It's likely that you have something like params.require(:key) in your controller. And your request is missing that parameter.
Rails will respond with 400 status in case you missed some require'd params.
What fixed it was switching from HTTP1.0 to HTTP1.1, adding the host header and changing the uri.
The logs didn't tell us anything, and the params were ok. The problem was not fully grasping the HTTP header requirements.

What does #_request.env['HTTP_X_MY_TOKEN'] return?

I'm not a ruby or rails programmer, but I'm tasked with reverse engineering an API for an RoR app. My HTTP POST requests are failing a validation check, where this line is supposed to provide a specific piece of data:
value = #_request.env['HTTP_X_MY_TOKEN'];
From what little experience I have and searching I've done, it appears to be looking for an HTTP request header MY_TOKEN but I'm unsure if that's the case.
My current HTTP request looks like this:
POST /myapp HTTP/1.1
Host: website.com:80
Content-Type: application/json
Content-Length: 12
my post data
If that is the case, can I simply add it to my HTTP post request headers as follows:
POST /myapp HTTP/1.1
Host: website.com:80
Content-Type: application/json
MY_TOKEN: sometokentext
Content-Length: 12
my post data
If not, how do I fill this value during my HTTP POST request?
Sending X-MY-TOKEN should do the trick.
As a side note, prepending custom headers with X- is no longer recommended and deprecated according to RFC-6648:
Custom HTTP headers : naming conventions

Adding News to D2L through valence

I'm hoping I can get some help with adding news the D2L. I've tried a lot and have gotten to the point where I don't know what else to try.
The error I keep on getting is 404. So, I'm thinking that either something is wrong with the URL I'm trying, or the data I'm sending (or maybe content type that is being sent).
I saw that when adding news, you need to pass it a multipart/mixed POST body. So, I've tried changing my code to include that, but I'm still not sure what is going on.
I don't think it's a permissions thing because I'm supposed to have full access with this account (and it's not 403, but 404)
This is the data I'm trying to send.
Overall Content Type:
ContentType: multipart/mixed;boundary=6da451c7
Data Being Sent:
--6da451c7
Content-Type: application/json
{"Title":"Test News Title","Body":{"Text":"Testing Testing 123...Testing Testing","Html":"<p>Testing Testing 123...Testing Testing</p>"},"StartDate":"2013-11-17T20:07:11Z","EndDate":"2013-12-02T20:07:11Z","IsGlobal":false,"IsPublished":false,"ShowOnlyInCourseOfferings":false}
--6da451c7
And here is the URL i'm trying to POST data to (slightly modified to not include personal data).
https://gsutest.desire2learn.com/d2l/api/le/1.3/6606/news/?x_a={{TOKEN}}&x_b={{TOKEN}}&x_c={{TOKEN}}&x_d={{TOKEN}}&x_t={{TIMESTAMP}}
I'm not sure where to go from here, any help would be nice. I realize I could be creating my POST body data wrong, but I'm just not sure what to try.
Thanks!
----Edit----
Ran a POST using fiddler and captured this data
POST https://gsutest.desire2learn.com/d2l/api/le/1.3/6606/news?x_a={{APPID}}&x_b={{USERID}}&x_c=OR0KIlHnHChrBvhHT99HVkH4WrD9dw_uPlpTGzKOdXc&x_d=b_TmyIHdTOL3U5bkNa1UNn11S4Yg7Cc3GOBoI911gLE&x_t={{TIMESTAMP}} HTTP/1.1
Content-Type: multipart/mixed;boundary=1649e26b
Host: gsutest.desire2learn.com
Content-Length: 342
Expect: 100-continue
Connection: Keep-Alive
--1649e26b
Content-Type: application/json
{"Title":"Test News Title","Body":{"Text":"Testing Testing 123...Testing Testing","Html":"<p>Testing Testing 123...Testing Testing</p>"},"StartDate":"2013-11-19T21:07:03.838Z","EndDate":"2013-12-04T21:07:01.413Z","IsGlobal":false,"IsPublished":false,"ShowOnlyInCourseOfferings":false}
--1649e26b
----Edit #2----
Ran another POST using fiddler and captured this data. The data that I'm sending came from: http://docs.valence.desire2learn.com/basic/fileupload.html#simple-uploads (under the upload to news section)
POST https://gsutest.desire2learn.com:443/d2l/api/le/1.3/6606/news/?x_a={{APP_ID}}&x_b={{USER_ID}}&x_c=rdzAFVUE6xBS24N5nE_4Hf5sbwpvJH1OVJaK4Ow-XT8&x_d=TmadrEGw55aKwS1uuNo68kvaR_pvYLUWJdsFa7LhrEQ&x_t={{TIMESTAMP}}" HTTP/1.1
Content-Type: multipart/mixed;boundary=xxBOUNDARYxx
Host: gsutest.desire2learn.com:443
Content-Length: 270
--xxBOUNDARYxx
Content-Type: application/json
{"EndDate": null, "IsPublished": false, "ShowOnlyInCourseOfferings": false,"Title": "Test title", "Body": {"Text": "Test body text", "HTML": null},"StartDate": "2013-02-20T13:15:30.067Z", "IsGlobal": false}
--xxBOUNDARYxx
I'm still getting "HTTP/1.1 404 Not Found" as the response headers.
Using the data you provided, I discovered that you are missing the millisecond value in your UTCDateTime format. By adding a millisecond value of .067 and .068 to each of the dates, I am able to POST successfully. I did this by using the Getting Started Sample against an LMS where I have an Instructor account with privileges to POST News items.

OData batch multipart format and Content-ID

I'm trying to implement an odata consumer, specifically right now related to doing batch operations and change sets, following the odata documentation essentially loads to this sample multipart batch that I've used as a basis.
However when I actually run this batch code (via fiddler request builder for example) updated with my own entity paths and such, I receive the following error:
Error processing batch request. At the
start of every operation, exactly two
headers need to be specified:
'Content-Type' and
'Content-Transfer-Encoding'. Make sure
these headers are present and have the
correct values.
If I remove the Content-ID from the change set the change set works correctly, but obviously the later operations no longer work because they reference this Content-ID.
I've attempted to move the Content-ID header out of the change request multipart.. part headers, and into the actual part payload request headers, ie:
--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1
POST /service.svc/Customers HTTP/1.1
Host: host
Content-Type: application/atom+xml;type=entry
Content-Length: ###
<AtomPub representation of a new Customer>
becomes
--changeset(77162fcd-b8da-41ac-a9f8-9357efbbd621)
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /service.svc/Customers HTTP/1.1
Host: host
Content-Type: application/atom+xml;type=entry
Content-Length: ###
Content-ID: 1
Again this no longer complains about the change set having only headers, but still the later reference the content id fails with
HTTP 404, Resource not found for the segment '$1'
The request part which references this content-id looks something like this:
--changeset_7448d3fc-39f6-49bb-b822-30fa4a1676ce
Content-Type: application/http
Content-Transfer-Encoding: binary
POST http://example.org/test.svc/$1/$links/Resources HTTP/1.1
Content-Type: application/json
.. json ..
Assume that http://example.org/test.svc is the service root.
The documentation isn't very clear really about the format of the inner request locations, so the path reference may be incorrect.
Hopefully somebody has better understood this aspect and can advise, thanks in advance.
Stephen.
Turns out you cannot refer to a change set request if the operation in this way if the operation isn't a POST, this makes sense from the aspect that only POST methods really require this reference, but it would be useful to not need this branching logic.
Importantly however the path when referencing the Content-ID should not be absolute, but instead simply:
POST $1/$links/Resources HTTP/1.1
Content-Type: application/json

Resources