HttpClient POST request to https - post

I'm working on a WinRT app that does login to a webpage and get some data. The problem is that I'm getting a "HttpRequestException: An error occurred while sending the request" message. Here is the code:
Uri url = new Uri("https://miyoigo-b.yoigo.com/selfcare/login");
HttpContent msg = new StringContent("account[cli]=" + number + "&password=" + pass);
HttpClientHandler handler = new HttpClientHandler();
handler.UseDefaultCredentials = true;
handler.UseCookies = true;
handler.CookieContainer = new CookieContainer();
HttpClient req = new HttpClient(handler);
req.DefaultRequestHeaders.Add("Host", "miyoigo-b.yoigo.com");
req.DefaultRequestHeaders.ExpectContinue = false;
HttpResponseMessage response = await req.PostAsync(url, msg);
string responseBody = await response.Content.ReadAsStringAsync();
I've been trying a lot of thing I found over the internet, even disabling my firewall, but nothing worked. I'm porting this from a Windows Phone app and it did work with this:
Uri url = new Uri("https://miyoigo-b.yoigo.com/selfcare/login");
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Method = "POST";
req.Headers["Host"] = "miyoigo-b.yoigo.com";
req.CookieContainer = new CookieContainer();
req.BeginGetRequestStream(new AsyncCallback(WriteCallback), req);
And afterwards, in the Callback I created a Stream and wrote the credentials.
Any idea?? I know that the problem is only with this webpage, maybe I'm forgetting to send something or the format of the POST content is not correct...
Thanks

Finally the problema was that Win8 Metro Apps only accepts SSL3.1 and this webpage was using SSL3.0. The solution was using the new version of the webpage.
Thank you all

Related

How to convert Office files to PDF using Microsoft Graph

I'm looking for a way to convert Office files to PDF.
I found out that Microsoft Graph could be used.
I'm trying to download converted PDF using Microsoft Graph from OneDrive.
I'd like to convert .docx to .pdf.
However, when I sent the following request, I did not receive a response even if I waited.
GET https://graph.microsoft.com/v1.0/users/{id}/drive/root:/test.docx:/content?format=pdf
Also, the error code is not returned.
If syntax is wrong, an error code will be returned as expected.
It will not return only when it is correct.
In addition, I can download the file if I do not convert.
GET https://graph.microsoft.com/v1.0/users/{id}/drive/root:/test.docx:/content
Is my method wrong or else I need conditions?
If possible, please give me sample code that you can actually do.
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
client.BaseAddress = new Uri(graphUrl);
var result = await client.GetAsync("/v1.0/users/xxxxxxxxxxxxxxxxxxxxxxxxx/drive/root:/test.docx:/content?format=pdf");
:
I would like to elaborate a bit Marc's answer by providing a few examples for HttpClient.
Since by default for HttpClient HttpClientHandler.AllowAutoRedirect property is set to True there is no need to explicitly follow HTTP redirection headers and the content could be downloaded like this:
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.BaseAddress = new Uri("https://graph.microsoft.com");
var response = await client.GetAsync($"/v1.0/drives/{driveId}/root:/{filePath}:/content?format=pdf");
//save content into file
using (var file = System.IO.File.Create(fileName))
{
var stream = await response.Content.ReadAsStreamAsync();
await stream.CopyToAsync(file);
}
}
In case if follow HTTP redirection is disabled, to download the converted file, your app must follow the Location header in the response as demonstrated below:
var handler = new HttpClientHandler()
{
AllowAutoRedirect = false
};
using (HttpClient client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.BaseAddress = new Uri("https://graph.microsoft.com");
var response = await client.GetAsync($"/v1.0/drives/{driveId}/root:/{filePath}:/content?format=pdf");
if(response.StatusCode == HttpStatusCode.Redirect)
{
response = await client.GetAsync(response.Headers.Location); //get the actual content
}
//save content into file
using (var file = System.IO.File.Create(fileName))
{
var stream = await response.Content.ReadAsStreamAsync();
await stream.CopyToAsync(file);
}
}
The API doesn't return the converted content directly, it returns a link to the converted file. From the documentation:
Returns a 302 Found response redirecting to a pre-authenticated download URL for the converted file.
To download the converted file, your app must follow the Location header in the response.
Pre-authenticated URLs are only valid for a short period of time (a few minutes) and do not require an Authorization header to access.
You need to capture the 302 and make a 2nd call to the URI in the Location header in order to download the converted file.

Post with Robospice and okHttp

I perform a POST using Robospice and okHttp :
public String loadDataFromNetwork() throws Exception {
uriBuilder = Uri.parse(url).buildUpon();
uri = new URI(uriBuilder.build().toString());
tmp = "user=" + user + "&password=" + pwd
HttpURLConnection connect = new OkUrlFactory(client).open(uri.toURL());
// Send post request
connect.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(connect.getOutputStream());
wr.writeBytes(tmp);
wr.flush();
wr.close();
// Read the response
in = connect.getInputStream();
}
Is there a better way to send a post (with Robospice/okHttp) ?
NB : my code is working fine, just want to know if it's correct or not...
The problem is that if I want to use the okHttp POST like that :
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, parameters))
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
with Robospice, RequestBody and newCall and isSuccessful cannot be resolved !
Do I have a solution to use okHttp post WITH Robospice ? (I know how to make a GET, but not a POST...)

JIRA rest api to fetch the activity stream

I am trying to get activity stream of my jira instance using the below api and it is not working , can anybody point me in the right direction ?
You should check this page out: https://developer.atlassian.com/docs/atlassian-platform-common-components/activity-streams/consuming-an-activity-streams-feed
The Atom feed of the activity stream works well only if you also log in in your feed reader.
Here is an example of consuming the activity stream through the Jira API using Basic Authentication. This is in C#, but the basic pattern can be applied anywhere:
string myJiraUsername = "username";
string myJiraPassword = "password"; //or API token
string authenticationHeaderValue = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(myJiraUsername + ":" + myJiraPassword));
System.Net.Http.HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authenticationHeaderValue);
Task<HttpResponseMessage> task = client.GetAsync("https://mycompany.atlassian.net/activity");
task.Wait();
HttpResponseMessage response = task.Result;
string resultOfApiCall = "";
if (response.IsSuccessStatusCode)
{
resultOfApiCall = response.Content.ReadAsStringAsync().Result;
Console.WriteLine("This was returned by your API request:\n" + resultOfApiCall);
}

How can I either fetch a CSRF token or send POST data through webbrowser

So what I'm trying to do is to login to a website, and then make a POST request. I've tried just making a webbrowser, and simply logging in there, then submitting the POST data with a button. I'm not sure if it isn't working this way because it's not being sent through webbrowser1 or because I'm not submitting the POST data correctly. Here was the code to submit the POST data.
HttpWebRequest req = (HttpWebRequest)
WebRequest.Create("url");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
string postData = "postdata";
req.ContentLength = postData.Length;
StreamWriter stOut = new
StreamWriter(req.GetRequestStream(),
System.Text.Encoding.ASCII);
stOut.Write(postData);
stOut.Close();
I also tried just logging in with one button, then with another button, submitting this POST data, but the problem is that it needs the CSRF token inside the POST request. Here is what I had so far.
string formUrl = "loginurl";
string formParams = string.Format("username={0}&password={1}&csrfmiddlewaretoken={2}", "user", "pass", "token");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];
What would be the best way of doing this? Thank you!
You can try binding to the "ajax:before" event in jquery to transparently add in a parameter for the CSRF token before sending off. How you would add the CSRF token in is dependent on what web framework you're using.

How to remove an attachment from Jira 4.4 using Http

I have been looking for a way to remove an attachment from Jira using the SOAP Api, but it seems that this is not possible natively, and I would prefer not having to implement a new plugin for Jira, as suggested in the accepted answer to this question, or recompiling the existing plugin to support this as mentioned here.
This answer to the abovementioned question seems to do exactly what I want, but alas, I can't get i to work. The response i get is an error stating that:
XSRF Security Token Missing
JIRA could not complete this action due to a missing form token.
You may have cleared your browser cookies, which could have resulted in the expiry of your current form token. A new form token has been reissued.
As I am using Asp.Net MVC C#, I have used the code from the answer, as is, with only the server url adjusted, as well as with different credentials (a Jira user) and the username/password passed through as request parameters using:
os_username=jirausername&os_password=xxxxxxx
The code I am currently using is as follows:
public void RemoveAttachment(string issueid, string attachmentid)
{
using (System.Net.WebClient client = new System.Net.WebClient())
{
//Compute jira server base url from WS url
string baseUrl = _service.Url.Substring(0, _service.Url.IndexOf("/rpc/"));
//Compute complete attachment url
string attachmenturl = baseUrl + "/secure/DeleteAttachment.jspa?id=" +
issueid + "&deleteAttachmentId=" + attachmentid;
client.Credentials = new System.Net.NetworkCredential("jirausername", "xxxxxxx");
string response = client.DownloadString(attachmenturl);
}
}
I ended up using a method that first requests the deletion confirmation form, then extracts a required token from the form, and finally posts something equivalent to the form content in order to delete the attachment. Code below.
public void RemoveAttachment(string issueid, string attachmentid)
{
//Compute jira server base url from WS url
string baseUrl = _service.Url.Substring(0, _service.Url.IndexOf("/rpc/"));
//Compute complete attachment deletion confirm url
string confirmurl = baseUrl + "/secure/DeleteAttachment!default.jspa?id=" +
issueid + "&deleteAttachmentId=" + attachmentid + "&os_username=jirauser&os_password=xxxxxx";
//Create a cookie container to maintain the xsrf security token cookie.
CookieContainer jiracontainer = new CookieContainer();
//Create a get request for the page containing the delete confirmation.
HttpWebRequest confirmrequest = (HttpWebRequest)WebRequest.Create(confirmurl);
confirmrequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
confirmrequest.CookieContainer = jiracontainer;
//Get the response and the responsestream.
WebResponse confirmdeleteresponse = confirmrequest.GetResponse();
Stream ReceiveStream = confirmdeleteresponse.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader confirmreader = new StreamReader(ReceiveStream);
// Read the content.
string confirmresponse = confirmreader.ReadToEnd();
//Create a regex to extract the atl/xsrf token from a hidden field. (Might be nicer to read it from a cookie, which should also be possible).
Regex atl_token_matcher = new Regex("<input[^>]*id=\"atl_token\"[^>]*value=\"(?<token>\\S+)\"[^>]*>", RegexOptions.Singleline);
Match token_match = atl_token_matcher.Match(confirmresponse);
if (token_match.Success)
{
//If we found the token get the value.
string token = token_match.Groups["token"].Value;
//Compute attachment delete url.
string deleteurl = baseUrl + "/secure/DeleteAttachment.jspa";
//Construct form data.
string postdata = "atl_token=" + HttpContext.Current.Server.UrlEncode(token) + "&id=" + issueid + "&deleteAttachmentId=" + attachmentid + "&Delete=Delete&os_username=jirauser&os_password=xxxxxx";
//Create a post request for the deletion page.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(deleteurl);
request.KeepAlive = false;
request.CookieContainer = jiracontainer; // Remember to set the cookiecontainer.
request.ProtocolVersion = HttpVersion.Version10;
request.Method = "POST";
//Turn our request string into a byte stream
byte[] postBytes = Encoding.ASCII.GetBytes(postdata);
//Make sure you specify the proper type.
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
//Send the post.
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
//Get the response.
WebResponse deleteresponse = request.GetResponse();
// Open the responsestream using a StreamReader for easy access.
StreamReader deleteresponsereader = new StreamReader(deleteresponse.GetResponseStream());
// Read the content.
string deleteresponsecontent = deleteresponsereader.ReadToEnd();
// do whatever validation/reporting with the response...
}
else
{
//We couldn't find the atl_token. Throw an error or something...
}
}
Edit:
Same thing works for removing comments. Replace 'attachment' with 'comment' and 'deleteAttachmentId' with 'commentId' and you should be good to go.

Resources