400 Bad Request : "Your request couldn't be completed" - ucwa batch request with postman - skype-for-business

I sendes this batch request with postman:
POST /ucwa/oauth/v1/applications/105177669305/batch HTTP/1.1
Host: lync.myDomain.com
Accept: multipart/batching
Content-Type: multipart/batching;boundary=6555373f-c163-b72d-5c00-c3cc6cb9cd52
Authorization: Bearer cwt=AAEBHAEFAAAAAAAFFQAAAJFDb5_gw6wKmbRiI5oNABENAxu_zcjj9Rt7KWK3RkJSKCAvAPgyCThFvNa0lFTBPm5usuFxhbNo5VqemqSOoI-qWc_fihdoYI4G_bjjSS1AgNENAxu_zcjj9Rt7KWK3RkJSI
X-Requested-With: xmlhttprequest
Cache-Control: no-cache
Postman-Token: 57195c61-6b6f-0db9-5760-0af268fe7d55
--6555373f-c163-b72d-5c00-c3cc6cb9cd52
Content-Type:application/http;msgtype=request
GET /ucwa/oauth/v1/applications/10513269305/people/contacts HTTP/1.1
Host:lync.myDomain.com
Accept:application/json
--6555373f-c163-b72d-5c00-c3cc6cb9cd52
Content-Type:application/http;msgtype=request
GET /ucwa/oauth/v1/applications/10513269305/me/presence HTTP/1.1
Host:lync.myDomain.com
Accept:application/json
--6555373f-c163-b72d-5c00-c3cc6cb9cd52--
and got response status "400 Bad Request" with "Your request couldn't be completed." message. Did i missed some headers? If you know any reason why i get this error, please, tell me.

From w3.org
HTTP Code 400 Bad Request means;
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
Check your request syntax. What kind of request format does your server expect? Would you be able to check server logs?

Lines need to end with Windows style line endings (\r\n), and should follow the format which is not even mentioned in the documentation
The following code is converted from batch.js in the UCWA samples, https://github.com/OfficeDev/skype-docs/blob/master/Skype/UCWA/samples/scripts/Batch.js
And the request limit in Batch is 100.
#Test
public void test() {
List<String> parts = new ArrayList<>();
String boundary = "77f2569d-c005-442b-b856-782305305e5f";
for (int i = 0; i < 100; i++) {
parts.add(createDataPart(boundary));
}
String data = parts.stream().collect(Collectors.joining("\r\n"));
data += "\r\n\r\n--" + boundary + "--\r\n";
try {
HttpResponse<String> response =
Unirest.post("https://lyncweb.example.com/ucwa/oauth/v1/applications/10820256145/batch")
.header("authorization", "Bearer cwt=CCCCHAEFAAAAAAAFFQAAANz03DsuQ6xAB-U7K3yFAACBEBUTVWulRKhftCre06OKSveCAgghgyBAJ_THbZjk1M3ICsm1apTszG7HcKGll6HUDlc4i_fEEoYIU0vz-ojC1QgNEBDrIobFox9WpyA_EhuC5Mk")
.header("content-type", "multipart/batching;boundary=" + boundary)
.header("accept", "multipart/batching")
.body(data)
.asString();
System.out.println("Response1 \r" + response.getBody());
} catch (UnirestException e) {
e.printStackTrace();
}
}
String createDataPart(String boundary) {
String dataPart = "\r\n--" + boundary;
dataPart += "\r\nContent-Type: application/http; msgtype=request\r\n";
dataPart += "\r\n" + "GET /ucwa/oauth/v1/applications/10820256145/people/test.user#example.com/presence HTTP/1.1";
dataPart += "\r\n" + "Host: " + "lyncweb.example.com";
dataPart += "\r\n" + "Accept: " + "application/json";
//if (part.Data) {
// dataPart += "\r\n" + "Data: " + JSON.stringify(part.Data);
//}
dataPart += "\r\n";
return dataPart;
}

Related

Model Binding returns null model

I have been unable to resolve an issue with Model Binding in an action.
It DOES bind, but not all of the time. Sometimes, the value is null and so of course it throws an error.
It seems to happen about 50% of the time, sometimes after the user has been logged in for a 4 minutes or longer.
This is the action:
[HttpPost]
public IActionResult Post([FromBody]Csr csr)
{
try
{
if(csr == null)
{
throw new Exception("Associate Controller recieved csr parameter when posting a new CSR");
}
//csr.ParentCsrId = this.GetCurrentCsr().CsrId;
csr.InsertedDate = DateTime.Now;
csr.UpdatedDate = DateTime.Now;
return Ok(_associateRepository.Add(csr));
}
catch (Exception ex)
{
LogException(ex, "Associate Controller", "Post([FromBody]Csr csr)");
throw ex;
}
}
The exception is thrown and logged correctly.
This is the data that was posted according to the browser:
Headers:
POST /api/associate HTTP/1.1
Host: portal.5-15globalenergy.it
Connection: keep-alive
Content-Length: 557
Accept: application/json
Origin: https://portal.5-15globalenergy.it
Authorization: Bearer xxxzy User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Content-Type: application/json
Referer: https://portal.5-15globalenergy.it/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Body:
{"csrTypeId":1,"countryId":2,"stateCode":"SO","birthCountryId":2,"birthStateCode":"SO","city":"Sondrio","streetPart":"STAZIONE","birthCity":"Sondrio","firstName":"Test","lastName":"User","maritalStatusId":2,"citizenshipCountryId":2,"personalTaxNum":"xxxxxx","streetName":"VIA SAN GOTTARDO","streetNum":"11","zip":"53216","landPhone":"231562145","mobilePhone":"231562145","email":"test#GMAIL.IT","bankAccountKey":"123625478325621","birthDate":"18/04/1969","orderStatusId":3,"streetCode":"","parentCsrId":"2130","syncStatusId":1,"languageId":3}
If there is an error in binding, is there a way to trap this?
I finally got this resolved. Here is the takeaway: If you get a null model, yet data was passed in the Web Request, it means that ModelBinding failed.
In my case, a misformatted date string could not be converted to a date. The result is the entire model is null, not just the data field.
The way to get the Errors is through the ModelState object. In my case, no error message was returned. But an Exception Object WAS returned.
Here is the code to concatenate it into a string:
string desc = "";
foreach (var modelState in ViewData.ModelState.Values)
{
foreach (var error in modelState.Errors)
{
if(!String.IsNullOrWhiteSpace(error.ErrorMessage))
desc = desc + " " + error.ErrorMessage.ToString();
if(error.Exception != null)
{
desc = desc + " Exception: " + error.Exception.ToString();
}
}
}

Http Status 415 even when providing correct ContentType

I'm attempting to set up a quick POC of an Autodesk Viewing App but I'm running into issues with authentication. I've already checked the following questions for general help but they're either covering extremely specific issues like HashTableMapping or haven't even been answered:
HTTP Status 415 - Unsupported Media Type when doing POST
HTTP status 415 when using Alamofire multipart upload
HTTP Error 500 when attempting to access localhost
The request failed with HTTP status 415
According to Autodesk's documentation my request structure is totally fine but seems to be throwing a 415 error. Anyone have any ideas or see something I'm not seeing? Here's my code below:
var XmlHttpRequest = require("xmlhttprequest").XMLHttpRequest;
console.log("references loaded");
var xhr = new XmlHttpRequest();
xhr.open("POST", "https://developer.api.autodesk.com/authentication/v1/authenticate", false);
var headerRequest = "Content-Type: application/x-www-form-urlencoded";
var headerValue =
"client_id=_someSecretValue_" + "&" +
"client_secret=_someOtherSecretValue_" + "&" +
"grant_type=client_credentials" + "&" +
"scope=data:read";
xhr.setRequestHeader(headerRequest, headerValue);
xhr.send();
console.log(xhr.status); //getting a 415 here
console.log(xhr.statusText);
Got it - was my own faulty logic that screwed me up. The first request header wasn't formatted properly and I needed to send my information as a value:
var XmlHttpRequest = require("xmlhttprequest").XMLHttpRequest;
console.log("references loaded");
var xhr = new XmlHttpRequest();
xhr.open("POST", "https://developer.api.autodesk.com/authentication/v1/authenticate", false);
//var headerRequest = "Content-Type:application/x-www-form-urlencoded";
var headerValue =
"client_id=_someSecretValue_" + "&" +
"client_secret=_otherSecretValue_" + "&" +
"grant_type=client_credentials" + "&" +
"scope=data:read";
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(headerValue);
console.log(xhr.status);
console.log(xhr.statusText);

Interact with a JSF application which use basic authentication programmatically

I am having difficulties interacting with a website which use basic authentication to authenticate the user.
I am working on visual basic and i have already tried to use
Dim req As HttpWebRequest = HttpWebRequest.Create("http://url.to.website.com")
adding the headers directly to the web request:
req.Headers.Add("Authorization: Basic " & Convert.ToBase64String(Encoding.Default.GetBytes("user" & ":" & "password")))
or using the network credentials:
req.Credentials = New Net.NetworkCredential("user", "password")
receiving always the same response code: 401 Unauthorized
Using Firefox developer tools i can analyze and resend some web requests and only using Firefox i am able to authenticate correctly.
Firefox report these headers:
Host: url.to.website.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http.//url.to.website.com/portal/data/pub
DNT: 1
Authorization: Basic ZmFrZTpwYXNzd29yZA==
Connection: keep-alive
So i have tried to set it manaually this way:
req.Host = "url.to.website.com"
req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"
req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
req.Referer = "https://url.to.website.com/some/path/to/file.jsf"
req.ContentType = "application/x-www-form-urlencoded"
req.KeepAlive = True
req.PreAuthenticate = True
req.Method = "POST"
req.Headers.Add("Authorization: Basic " & Convert.ToBase64String(Encoding.Default.GetBytes("user" & ":" & "password")))
with no success (receiving always the same response code: 401 Unauthorized)
Another try was with a web-browser:
WebBrowser1.Navigate("url", Nothing, Nothing, "Authorization: Basic " & Convert.ToBase64String(Encoding.Default.GetBytes(AUTH_USER & ":" & AUTH_PASSWORD)))
My objective is to authenticate, then query some pages and collect responses in order to parse them and use it later in the application.
How can i solve the issue about authentication?
The website is written using JSF and i have no control over it.
Update:
My problem is about authentication, not yet about the jsf application.
While using Firefox all work fine (I can send a request to the website and it will authenticate me right) but while using the HttpWebRequest the authentication fails, even if I set the same headers, as Written before .
I have to figure out the difference between the two requests
I had to get this working for Dukes Forest Java EE Tutorial Port to Wildfly. The code was already written, but the header was case sensitive. Anyway, the code used there is as follows:
/* Client filter for basic HTTP auth */
class AuthClientRequestFilter implements ClientRequestFilter {
private final String user;
private final String password;
public AuthClientRequestFilter(String user, String password) {
this.user = user;
this.password = password;
}
#Override
public void filter(ClientRequestContext requestContext) throws IOException {
try {
requestContext.getHeaders().add(
"Authorization",
"Basic " + DatatypeConverter.printBase64Binary(
(user+":"+password).getBytes("UTF-8"))
);
} catch (UnsupportedEncodingException ex) { }
}
}
The DatatypeConverter is imported from javax.xml.bind. This code was called from the following routine, which has the HTTPClient:
Client client = ClientBuilder.newClient();
client.register(new AuthClientRequestFilter("jack#example.com", "1234"));
Response resp = client.target(ENDPOINT)
.request(MediaType.APPLICATION_XML)
.post(Entity.entity(order, MediaType.APPLICATION_XML), Response.class);
int status = resp.getStatus();
if (status == 200) {
success = true;
}
logger.log(Level.INFO, "[PaymentHandler] Response status {0}", status);
client.close();
return success;
This client code posts to a RESTful service.

Create a new calendar from CalDav API

I am trying to create a new calendar in my principal's home folder using SabreDav.
I couldn't find how to achieve this - is it even possible ?
UPDATE:
I found out about MKCALENDAR method, but the following returns an "abandoned" request error:
<C:mkcalendar xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:ical="http://apple.com/ns/ical/" >"
<D:set>
<D:prop>
<D:displayname>cal Display Name</D:displayname>
<ical:calendar-color>cal Color</ical:calendar-color>
</D:prop>
</D:set>
</C:mkcalendar>
Sending it with a HttpWebRequest fails with a canceled request messgage...
Thanks in advance!
UPDATE 2:
Some more details:
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create("http://my.sabredavcalendar.srv/calendarserver.php/calendars/admin/my_new_calendar/");
Request.Method = "MKCALENDAR";
Request..Credentials = new NetworkCredentials("usr", "pwd");
Request.ContentType = "application/xml";
string body = "<C:mkcalendar [.....] </C:mkcalendar>";
Request.ContentLength = body.Length;
// ---
// The using block throws an error...
using (Stream reqStream = Request.GetRequestStream()) {
byte[] encodedBody = Encoding.UTF8.GetBytes(body);
reqStream.Write(encodedBody, 0, encodedBody.Length);
reqStream.Close();
}
Response = (HttpWebResponse)Request.GetResponse();
The error message I get is
The request was aborted: The request was canceled
On the server side, here is the access log:
192.168.1.200 - - [06/Jul/2015:09:51:48 +0200] "MKCALENDAR /calendarserver.php/calendars/admin/my_new_calendar/ HTTP/1.1" 400 25 "-" "-"
The error log is empty... so it seems I get a "bad request" response which is not caught when preparing the request?!
UPDATE 3: the body contains special characters as "éàê..." which is why the contentlength part was wrong !
I take hnh's comment as an answer: the problem was indeed the Request.ContentLength = body.Length.
Corrected code is:
Request.ContentLength = Encoding.UTF8.GetByteCount(body);

jetty ServletTester to POST a file?

Can I use jetty's ServletTester to send file by POST method? How? I tried to send raw request string:
String reqString = "POST /avScan HTTP/1.1\r\n" +
"Host: tester\r\n" +
"\r\n" +
"Content-Type: multipart/form-data; boundary=---------------------------121396480018623072891156223118\r\n" +
"Content-Length: 63\r\n" +
"-----------------------------121396480018623072891156223118\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"test-file\"\r\n" +
"Content-Type: application/octet-stream\r\n" +
"Just some text file.\r\n" +
"-----------------------------121396480018623072891156223118--\r\n";
ServletTester tester = new ServletTester();
tester.addServlet(FileReceiver.class, "/avScan");
tester.start();
HttpTester request = new HttpTester();
request.setContent(reqString);
String responseString = tester.getResponses(request.generate()); //Exception thrown
HttpTester response = new HttpTester();
response.parse(responseString);
However, I get java.lang.IllegalStateException: State==HEADER where I marked it in the code.
Can I test POST servlet receiving files with ServletTester? If not, what tool would you recommend?
From Jetty's MultipartFilterTest.java :
HttpTester request = new HttpTester();
String boundary="XyXyXy";
request.setHeader("Content-Type","multipart/form-data; boundary="+boundary);
String content = "--" + boundary + "\r\n"+
"Content-Disposition: form-data; name=\"fileup\"; filename=\"test.upload\"\r\n"+
"Content-Type: application/octet-stream\r\n\r\n"+
"How now brown cow."+
"\r\n--" + boundary + "-\r\n\r\n";
request.setContent(content);