I've got a problem with sending POST request to the apache server with htaccess using WebClient (I've tryed to using HttpRequest as well as WebRequest but it had the same result).
I've got the following example from vendor on PHP:
$soap = curl_init(url);
curl_setopt($soap, CURLOPT_POST, 1);
curl_setopt($soap, CURLOPT_RETURNTRANSFER, 1);
$XML = file_get_contents("test.xml");
$request = <<<XML
$XML
XML;
curl_setopt($soap, CURLOPT_HTTPHEADER, array('Content-Type: text/xml; charset=utf-8', 'Content-Length: '.strlen($request)));
curl_setopt($soap, CURLOPT_POSTFIELDS, $request);
$response = curl_exec($soap);
curl_close($soap);
My version on C# is:
public static string Post(string login, string password, string url, string content) {
var result = String.Empty;
var uri = new Uri(url);
using (var client = new WebClient()) {
client.Credentials = new NetworkCredential(login, password);
client.Encoding = Encoding.UTF8;
client.Headers[HttpRequestHeader.ContentType] = "text/xml; charset=UTF-8";
client.Headers[HttpRequestHeader.Accept] = "application/xml";
result = client.UploadString(uri, content);
}
return result;
}
When I run the program I've got an exception with 400 error (bad request). I've sniff the request using Fiddler2 and found the following error message: "Request header field is missing ':' separator"
Can anyone help me found what is wrong in the request and why a server reject the request?
P.S: Request header
POST http://production.is.topdelivery.ru/tests/xmlGate/index.php HTTP/1.1
Content-Type: text/xml; charset=utf-8
Authorization: Basic YmFiYWR1OmJhYmFkdXBhc3M=
Host: production.is.topdelivery.ru
Content-Length: 1617
Expect: 100-continue
In my case following code works properly
private string post(string content)
{
var result = String.Empty;
var uri = new Uri(_url);
WebRequest req = HttpWebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "text/xml";
String encoded = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("user:pass"));
req.Headers.Add("Authorization", "Basic " + encoded);
using (var s = req.GetRequestStream())
using (var sw = new StreamWriter(s, Encoding.UTF8))
{
sw.Write(content);
}
using (var s = req.GetResponse().GetResponseStream())
using (var sr = new StreamReader(s, Encoding.UTF8))
{
result = sr.ReadToEnd();
};
return result;
}
This helped me. I was having an issue with a newer release of Apache not seeing the credentials even though there was no issue with an older version. I changed
client.Credentials = new NetworkCredential(login, password);
to
String encoded = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("user:pass"));
req.Headers.Add("Authorization", "Basic " + encoded);
and it worked!
Thank you.
Related
I'm working on setting up an authorized restful request and I'm having a hell of a time getting a valid response back. If I paste the request URL into a browser(Firefox Quantum and Chrome) I can get a response of Status:Authenticated;token:[token string] but when I try WebRequest.Create([url]) I keep getting a response of "400: bad request". I'm copying the URL straight from debug code so I know it's valid. I'm pretty sure I'm doing something simple wrong. Would someone point me in the right direction?
string loginReq = _authPath + "?user=" + _username + "&pw=" + _password;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginReq);
request.Accept = "text/html, application/xhtml + xml, */*";
request.UserAgent = "Mozilla/5.0(Windows NT 6.1; WOW64; Trident/7.0; rv: 11.0) like Gecko";
request.KeepAlive = true;
WebResponse response = request.GetResponse();
Console.WriteLine(response.ResponseUri);
Console.Read();
Ok, after doing some more poking it looks like the site I'm calling is refusing the request because it thinks I'm using IE9. Here's the latest version of the code
private static string GetAuthorization() {
string token = string.Empty;
string loginReq = _authPath + "?user=" + _ftpUsername + "&pw=" + _ftpPassword;
string task = SendWebRequest(loginReq);
//HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginReq);
//request.Accept = "text/html, application/xhtml + xml, */*";
//request.UserAgent = "Mozilla/5.0(Windows NT 6.1; WOW64; Trident/7.0; rv: 11.0) like Gecko";
//request.KeepAlive = true;
//request.Headers.Add("Accept-Encoding", "gzip, deflate");
//request.Headers.Add("Cache-Control", "no-cache");
//request.Headers.Add("Accept-Language", "en-US");
//request.Headers.Add("DNT", "1");
//request.Method = "GET";
//request.CookieContainer = new CookieContainer();
//request.Headers.Add("Request", "GET /xc2/QAPI_Upload?user=user#ottrtest1.com&pw=ETqDJeQ1! HTTP/1.1");
//HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(task);
Console.Read();
return token;
}
public static string SendWebRequest(string requestUrl) {
using (HttpClient client = new HttpClient())
using (HttpResponseMessage response = client.GetAsync(requestUrl).GetAwaiter().GetResult())
return response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
I keep trying different things but I'm getting the same results(400 Bad Request) Here's the latest version of what I'm working with
string loginReq = $"{_authPath}?user={_userName}&pw={_passWord}";
string result;
using (WebClient wc = new WebClient()) {
var json = wc.DownloadString(loginReq);
result = json.ToString();
Console.WriteLine(json);
}
If I change the url to "https://www.google.com" my code works. if I paste loginReq into SoapUI it works, I can't get the url and my code to work together...
Fiddler found the problem. Once I reviewed the request in fiddler I saw that I needed to set the security protocol type to tls1.0, tls1.1, or tls1.2. Once I did that I finally got the call to work. Here's the working code in case anyone needs it for reference:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
string loginReq = $"{_authPath}?user={_userName}&pw={_passWord}";
string result;
using (WebClient wc = new WebClient()) {
var json = wc.DownloadString(loginReq);
result = json.ToString();
Console.WriteLine(json);
}
return result;
Fiddler found the problem. Once I reviewed the request in fiddler I saw that I needed to set the security protocol type to tls1.0, tls1.1, or tls1.2. Once I did that I finally got the call to work. Here's the working code in case anyone needs it for reference:
ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
string loginReq = $"{_authPath}?user={_userName}&pw={_passWord}";
string result;
using (WebClient wc = new WebClient()) {
var json = wc.DownloadString(loginReq);
result = json.ToString();
Console.WriteLine(json);
}
return result;
I'm a C# developer I need to use webhooks to get some stuff after the gethostpage with redirect.
Everything it's fine if I use GET ( get events, get my webhooks ), but when I'm going to create a new webhook I get a "The remote server returned an error: (400) Bad Request." for sure it's a stupid thing but I'm stuck.
Any tips?
The request
byte[] encoded = System.Text.Encoding.Default.GetBytes(apiLogin + ":" + transactionKey);
string base64 = System.Convert.ToBase64String(encoded);
var isPost = !string.IsNullOrWhiteSpace(json);
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = isPost ? "POST" : "GET";
httpWebRequest.Headers.Add("Authorization", "Basic " + base64);
httpWebRequest.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
if (isPost)
{
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
}
}
string result = null;
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
result = streamReader.ReadToEnd();
return result;
}
return result;
I'm trying the JSON sample from documentation sample
Found, it is need to create a signature in merchant panel before use "post" webhooks, "get" works also without doing it
Following is the API Call i make using postman and get a ticket back in the response body (screenshot):
I am not able to get the ticket in a HttpWebRequest Response in C#. Please below see the small sample code:
C# code
HttpWebRequest Request = WebRequest.Create(strUrl) as HttpWebRequest;
Request.Method = "POST";
Request.Headers.Add("Authorization", "Basic <>");
//Request.ContentType = "application/form-data";
Request.KeepAlive = true;
string data = string.Format("username=" + UserName + "&password=" + Password);
byte[] dataStream = Encoding.UTF8.GetBytes(data);
Request.ContentLength = dataStream.Length;
using (Stream newStream = Request.GetRequestStream())
{
// Send the data.
newStream.Write(dataStream, 0, dataStream.Length);
newStream.Close();
}
var Response = (HttpWebResponse)Request.GetResponse();
using (var stream = Response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
if (Response.StatusCode != HttpStatusCode.OK)
throw new Exception("The request did not complete successfully and returned status code " + Response.StatusCode);
ResponseTicket strTicket= JsonConvert.DeserializeObject<ResponseTicket>(reader.ToString());
JsonConvert.DeserializeObject(Response.GetResponseStream().ToString());
MessageBox.Show(strTicket.Ticket);
}
Where as statuscode=200. But the content length is 0.
It is very difficult to find any meaning full help on CS10.5 API. I have checked there AppWorks platform but in vain. Would appreciate if someone can find the problem in the code, which apparently i can not see.
I don't know if this is still an issue for you. For me it was also, but figured it out:
public string LoginAsAdminAndRetrieveTicket(string userName, string passWord, string domain, string url)
{
var uri = $"http://{url}/otcs/llisapi.dll/api/v1/auth";
var request = new HttpRequestMessage();
request.Headers.Add("Connection", new[] { "Keep-Alive" });
request.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
request.Headers.Add("Pragma", "no-cache");
request.RequestUri = new Uri(uri);
request.Method = HttpMethod.Post;
request.Content = new StringContent($"username={userName};password={passWord}", Encoding.UTF8, "application/x-www-form-urlencoded");
var httpClientHandler = new HttpClientHandler
{
Proxy = WebRequest.GetSystemWebProxy(),
UseProxy = true,
AllowAutoRedirect = true
};
using (var client = new HttpClient(httpClientHandler))
{
var response = client.SendAsync(request).Result;
string ticket;
var vals = response.Headers.TryGetValues("OTCSTicket", out IEnumerable<string> temp) ? temp : new List<string>();
if (vals.Any())
{
ticket = vals.First();
}
return response.Content.ReadAsStringAsync().Result;
}
}
I have to upload a file to third party server using REST API. I have bare minimum document is available for that REST method.
When I use Postman to call the service, it works. Part of the generated code in Postman for C# is like this :
var client = new RestClient("<URL>");
var request = new RestRequest(Method.POST);
request.AddHeader("postman-token", "6cb9f00b-e1ac-f8d8-b5d6-eeb67b06ae6a");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("authorization", "Basic cm9vdDpIaXRhY2hpQDEy");
request.AddHeader("content-type", "multipart/form-data; boundary=-- -011000010111000001101001");
request.AddParameter("multipart/form-data; boundary=-- -011000010111000001101001", "-----011000010111000001101001\r\nContent- Disposition: form-data; name=\"file\"; filename=\"[object Object]\"\r\nContent-Type: false\r\n\r\n\r\n-----011000010111000001101001--", ParameterType.RequestBody);
RestResponse response = client.Execute(request);
The following code written in Python also works –
vroAuth = requests.auth.HTTPBasicAuth("<username>","<Password> ")
url = <url>
files = {"file":open("<absolute file path on client machine>",'rb')}
response_output = requests.post(url, auth=vroAuth,files=files, verify=False)
Based on these two code snippets ,I tried to write client code in C# like this:
HttpWebRequest request = HttpWebRequest.Create(restBaseUrl) as HttpWebRequest;
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
ServicePoint sp = request.ServicePoint;
var fl = Path.GetFileName(fileName);
request.Method = "POST";
request.Timeout = 60 * 60 * 1000;
request.Accept = "application/json";
request.AllowAutoRedirect = false;
String headerInfo = "file; filename=" + fileName;
request.Headers["Content-Disposition"] = headerInfo;
request.ContentType = "multipart/form-data;";
request.Credentials = new NetworkCredential(userName, password);
using (var strm = request.GetRequestStream())
{
using (var file = File.OpenRead(fileName))
{
file.CopyTo(strm);
}
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
There , I am getting “error 500 – Internal server error”. Unfortunately, there is no information in the header returned from the server. If I try different Content Type for request ( for example - "application/octet-stream";, I am getting error 415 – Media type not supported). All I know is “file” is one of the parameters with Data type as “File”. Any suggestion, how can I proceed to resolve the issue ?
I'm looking for solution to send request with JSON like parameter to server.
I use this code,
var httpClient = new HttpClient();
var tempByteArray = Encoding.UTF8.GetBytes("my valid json");
var stream = new MemoryStream(tempByteArray);
var streamContent = new StreamContent(stream);
var request = new HttpRequestMessage(HttpMethod.Post, Constants.LocalServer);
request.Content = streamContent;
request.Headers.TransferEncodingChunked = true;
HttpResponseMessage response = await httpClient.SendAsync(request);
But in response I get:
{
StatusCode: 501,
ReasonPhrase: 'NotImplemented',
Version: 1.0,
Content: System.Net.Http.StreamContent,
Headers: {
X-Squid-Error: ERR_UNSUP_REQ0X-Cache: MISSfromproxy3.itos.orgX-Cache-Lookup: NONEfromproxy3.companyname.org: portProxy-Connection: closeDate: Thu,
18Apr201309: 17: 53GMTServer: squid/2.6.STABLE21Via: 1.0proxy3.companyname.org: port(squid/2.6.STABLE21)Content-Length: 1099Content-Type: text/htmlExpires: Thu,
18Apr201309: 17: 53GMT
}
}
May be have another way to sent request with json parameter on Win8?
UPDATE I found solution:
public static async Task<string> LoadData(string json, string serverUrl)
{
var request = (HttpWebRequest)WebRequest.Create(new Uri(Constants.LocalServer));
request.ContentType = "application/json";
request.Method = "POST";
using (var requestStream = await request.GetRequestStreamAsync())
{
var writer = new StreamWriter(requestStream);
writer.Write(json);
writer.Flush();
}
using (var resp = await request.GetResponseAsync())
{
using (var responseStream = resp.GetResponseStream())
{
var reader = new StreamReader(responseStream);
return = reader.ReadToEnd();
}
}
}
It's work great, but must exists more simple way(i hope). And I'll try to find it.
When I post data using your two code snippets, I see some differences in the requests.
Here is the raw post for the first code sample (that you say does not work):
POST http://testing.foo.com/api/Values HTTP/1.1
Host: testing.foo.com
Expect: 100-continue
Connection: Keep-Alive
Content-Length: 75
{
id:"1",
title:"title text",
post:"post text",
isDeleted:"False"
}
This is the raw post for the code in your update (code that you say works):
POST http://testing.foo.com/api/Values HTTP/1.1
Content-Type: application/json
Host: testing.foo.com
Content-Length: 75
Expect: 100-continue
{
id:"2",
title:"title text",
post:"post text",
isDeleted:"False"
}
The differences in the two requests are as follows:
In the first request, the content type is never set.
In the first request, the content is UTF8 encoded.
To fix your non-working code, I would suggest you try one or both of the following:
Set the content type to application/json
Not UTF8 encode the request
At that moment this solution is most useful.
public static async Task<string> LoadData(string json, string serverUrl)
{
var request = (HttpWebRequest)WebRequest.Create(new Uri(Constants.LocalServer));
request.ContentType = "application/json";
request.Method = "POST";
using (var requestStream = await request.GetRequestStreamAsync())
{
var writer = new StreamWriter(requestStream);
writer.Write(json);
writer.Flush();
}
using (var resp = await request.GetResponseAsync())
{
using (var responseStream = resp.GetResponseStream())
{
var reader = new StreamReader(responseStream);
return = reader.ReadToEnd();
}
}
}