ConvertApi doesn't follow HTTP 302 Redirect - c#

I'm trying to convert a file which is located on a remote server.
I use ConvertApi for .NET.
My code:
string url = "http://test.com/myfile";
var convertApi = new ConvertApi("secret");
var response = await convertApi.ConvertAsync("web", "pdf", new ConvertApiParam("url", url));
This code fails (ConvertApi returns HTTP 500 Internal Server Error) because the remote server returns HTTP 302 Redirect with the exact file location.
But ConvertApi doesn't follow this redirect for some reason.
HTTP 302 Redirect is a very common way for file storage services to handle such downloads.
Is it a bug? Am I missing something? Maybe there is a special setting that forces ConvertApi to follow redirects?

The correct usage to convert remote file is below. You should use ConvertApiFileParam class to pass file as remote file url wrapped into Uri object.
var convertApi = new ConvertApi("secret");
var sourceFile = new Uri("https://github.com/Baltsoft/CDN/raw/master/cara/testfiles/presentation2.pptx");
var convertToPdf = convertApi.ConvertAsync("pptx", "pdf", new ConvertApiFileParam(sourceFile));

Related

Download a file with the Microsoft Graph c# SDK by the file's full URL

I have a list of fully qualified URLs and I am looking to download the files out of SharePoint and business OneDrive folders. The URLs are as follows:
https://tenant-my.sharepoint.com/personal/bob_smith_tenant_onmicrosoft_com/Documents/Microsoft Teams Chat Files/file.csv
https://tenant.sharepoint.com/sites/Development/Shared%20Documents/General/file2.pdf
I am not seeing a way with the Graph SDK to directly download files. I have successfully download the SharePoint file with CSOM but I'd prefer to use Graph so it can handle both file types if possible. Does anyone know if this is possible? Thanks in advance
When it comes to addressing resource by Url in OneDrive API, shares endpoint comes to the rescue. In that case the flow for downloading a file by full url could consists of the following steps:
first step would be to transform the URL into a sharing token (see
below section), for that matter we utilize shares endpoint
once the sharing token is generated, the OneDrive API request to
download a file could be constructed like this:
/shares/{shareIdOrEncodedSharingUrl}/driveitem/content
Example
const string fileFullUrl = "https://contoso-my.sharepoint.com/personal/jdoe_contoso_onmicrosoft_com/documents/sample.docx";
var sharedItemId = UrlToSharingToken(fileFullUrl);
var requestUrl = $"{graphClient.BaseUrl}/shares/{sharedItemId}/driveitem/content";
var message = new HttpRequestMessage(HttpMethod.Get, requestUrl);
await graphClient.AuthenticationProvider.AuthenticateRequestAsync(message);
var response = await graphClient.HttpProvider.SendAsync(message);
var bytesContent = await response.Content.ReadAsByteArrayAsync();
System.IO.File.WriteAllBytes("sample.docx", bytesContent); //save into local file
How to transform the URL into a sharing token
The following snippet demonstrates how to transform the URL into a sharing token (adapted from here)
static string UrlToSharingToken(string inputUrl)
{
var base64Value = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(inputUrl));
return "u!" + base64Value.TrimEnd('=').Replace('/', '_').Replace('+', '-');
}

Get instance of ApiController class from a URL directly

I am looking for a way to call the appropriate method (get, post etc.) on an ApiController class based on the URL and request type etc. without making a http request.
Background: We have an API application with numerous controllers that needs to also accept requests from a remote server. Due to restrictions I cannot control there is no way to open ports between the two servers to allow the remote server to make the request directly so we decided to forward the data using websockets (SignalR). I can send (within reason) whatever information is required.
I have tried the below:
HttpRequestMessage request = new HttpRequestMessage();
var bld = new UriBuilder
{
Port = 123,
Path = "api/v1/search",
Query = "query=search_string"
};
request.RequestUri = bld.Uri;
var httpCfg = AppConfiguration.Get().HttpConfig; //this is the same config that UseWebApi was called with and contains the routes.
var route = httpCfg.Routes.GetRouteData(request);
var controllerSelector = new DefaultHttpControllerSelector(httpCfg);
var descriptor = controllerSelector.SelectController(request);
route contains the controller name (search) but the call to SelectController throws an exception with a 404 response in it (I presume this indicates I am missing something from the fake request). The same URI works when sent as a direct http request so the routes do work as best I can tell.
Is there a better way to do this, or if not what am I missing from the request that is causing the 404?

Why does WebClient.UploadValues overwrites my html web page?

I'm familiar with Winform and WPF, but new to web developing. One day saw WebClient.UploadValues and decided to try it.
static void Main(string[] args)
{
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["thing1"] = "hello";
values["thing2"] = "world";
//A single file that contains plain html
var response = client.UploadValues("D:\\page.html", values);
var responseString = Encoding.Default.GetString(response);
Console.WriteLine(responseString);
}
Console.ReadLine();
}
After run, nothing printed, and the html file content becomes like this:
thing1=hello&thing2=world
Could anyone explain it, thanks!
The UploadValues method is intended to be used with the HTTP protocol. This means that you need to host your html on a web server and make the request like that:
var response = client.UploadValues("http://some_server/page.html", values);
In this case the method will send the values to the server by using application/x-www-form-urlencoded encoding and it will return the response from the HTTP request.
I have never used the UploadValues with a local file and the documentation doesn't seem to mention anything about it. They only mention HTTP or FTP protocols. So I suppose that this is some side effect when using it with a local file -> it simply overwrites the contents of this file with the payload that is being sent.
You are using WebClient not as it was intended.
The purpose of WebClient.UploadValues is to upload the specified name/value collection to the resource identified by the specified URI.
But it should not be some local file on your disk, but instead it should be some web-service listening for requests and issuing responces.

Creating directory on server using HttpWebRequest

I am trying to create directory on server via https. But while returning the response it generates exceptions: “The remote server returned an error: (404) Not Found.”
The code is as follows:
string szURL3 = #"https://directoryurl/TestDir/";
//Create an HTTP request for the URL.
HttpWebRequest httpMkColRequest = (HttpWebRequest)WebRequest.Create(szURL3);
// Set up new credentials.
httpMkColRequest.Credentials = new NetworkCredential(_httpsUserName, _httpsPassword);
// Pre-authenticate the request.
httpMkColRequest.PreAuthenticate = true;
// Define the HTTP method.
httpMkColRequest.Method = #"MKCOL";
// Retrieve the response.
HttpWebResponse httpMkColResponse = (HttpWebResponse)httpMkColRequest.GetResponse();
//Write the response status to the console.
Console.WriteLine(#"MKCOL Response: {0}",httpMkColResponse.StatusDescription);
Could anybody support regarding this. I am able to get the directory information correctly in the same way. As I referred some links:
http://blogs.msdn.com/b/robert_mcmurray/archive/2011/10/18/sending-webdav-requests-in-net-revisited.aspx
According to this, what I understood is that the resources are locked. But how to unlock the resources for creating directory.
Please correct where modification required.
I solved the issue. The webDAV Configuration on the server was not enabled.

Resend HTTP header

I have application. It send request to my proxy class. Proxy must to parse http header string (I done this) and resend it request to server to get a video.
At first, mediacomponent connect to proxy:
var uri = new Uri("http://127.0.0.1:2233/files/1.mp4");
videoPlayer.Source = uri;
Play();
Proxy get http header string
"GET /files/1.mp4 HTTP/1.1\r\nCache-Control: no-cache\r\nConnection: Keep-Alive\r\nPragma: getIfoFileURI.dlna.org\r\nAccept: */*\r\nUser-Agent: NSPlayer/12.00.7601.17514 WMFSDK/12.00.7601.17514\r\nGetContentFeatures.DLNA.ORG: 1\r\nHost: 127.0.0.1:2233\r\n\r\n"
I replase host:
"GET /files/1.mp4 HTTP/1.1\r\nCache-Control: no-cache\r\nConnection: Keep-Alive\r\nPragma: getIfoFileURI.dlna.org\r\nAccept: */*\r\nUser-Agent: NSPlayer/12.00.7601.17514 WMFSDK/12.00.7601.17514\r\nGetContentFeatures.DLNA.ORG: 1\r\nHost: myserver.ru\r\n\r\n"
Now proxy must get video from server. What must I do?
When using .NET, you don't have to manually create the HTTP message itself. Instead, use the classes in the System.Net.Http namespace to form and send an HTTP message and process the response.
For example, sending an HTTP GET message to a URL can be as simple as:
var uri = new Uri("http://www.foobar.com/");
var client = new HttpClient();
string body = await client.GetStringAsync(uri);
Note that this general approach will download the entire contents of the resource at the given URI. In your case, you may not want to wait for the whole video to download before you start playing/processing/storing it. In which case, you might want to use the HttpClient.ReadAsStream() method which will return a stream from which you can read until the stream closes.

Categories