c# TcpClient Post returning empty results - c#

I have the following code:
string url = "https://myurl.com/is/here/example?param1=100&param2=200";
string post = "POST " + url + " HTTP/1.1\r\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
"Accept-Encoding: gzip, deflate\r\n" +
"Accept-Language: en-US,en;q=0.5\r\n" +
"Connection: keep-alive\r\n" +
"Host: myurl.com\r\n" +
"User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0\r\n" +
"Content-type: application/json\r\n" +
"X-HTTP-Method-Override: GET\r\n" +
"X-MY-CUSTOM-HEADER: headervalue\r\n\r\n";
TcpClient tcp = new TcpClient("myurl.com", 443);
string returnData = string.Empty;
using (SslStream stream = new SslStream(tcp.GetStream()))
{
//Authenticate here...
byte[] data = Encoding.ASCII.GetBytes(post);
stream.Write(data, 0, data.Length);
stream.Flush();
stream.ReadByte();
data = new byte[4096];
var n = stream.Read(data, 0, data.Length);
using (MemoryStream ms = new MemoryStream(data, 0, n))
{
ms.ReadByte();
ms.ReadByte();
using (DeflateStream df = new DeflateStream(ms, CompressionMode.Decompress))
using (StreamReader rd = new StreamReader(df))
{
returnData = rd.ReadToEnd();
}
}
}
tcp.Close();
However, the response is always empty. Is the post string correct? What am I missing here?
Edit:
I'm using SslStream and it seems to be retrieving data. However, Is there a way to just read till all data is received instead of

It appears that you're declaring the length of content to by the length of your URL (when expressed as UTF-8), rather than whatever is in the post body
If the content is not as long as the content-length header indicates, I would expect the remote server to wait for the rest of the content.
You're also connecting to port 443, and your URL starts 'https' but you don't appear to be making any attempt to do the SSL negotiation.

Related

http post using tcpclient in c# not working

Hi i am trying to post to login page using tcpclient class . but it says 302 error. same thing i can do using webclient. please suggest where i am missing something. i have already achieved using webclient class. but i have asked to do at lower level. please suggest.
i have tried following
string sPost = "POST http://www.udupikrishnarestaurant.com/ HTTP/1.1\r\n" +
"Host: www.udupikrishnarestaurant.com\r\n" +
"Connection: keep-alive\r\n" +
"Content-Length: 632\r\n" +
"Cache-Control: max-age=0\r\n" +
"Origin: http://www.udupikrishnarestaurant.com \r\n" +
"Upgrade-Insecure-Requests: 1\r\n" +
"User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36 \r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 \r\n" +
"Referer: http://www.udupikrishnarestaurant.com/ \r\n" +
"Accept-Encoding: gzip, deflate, br\r\n" +
"Accept-Language: en-US,en;q=0.8\r\n" +
"\r\n" +
"__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=/wEPDwUKLTM0ODY4NTA5Mg9kFgRmD2QWAgIBDxYCHgdWaXNpYmxlaGQCAQ8WAh4EVGV4dAUOMTgyLjY5LjEwOC4yMTFkGAEFHl9fQ29udHJvbHNSZXF1aXJlUG9zdEJhY2tLZXlfXxYCBQlidG5TdWJtaXQFCWJ0bkZvcmdvdCvBSicNzlFc1g4UTZeO96HhGK8T&__VIEWSTATEGENERATOR=CA0B0334&__EVENTVALIDATION=/wEdAAr0HIr+WBkxh8yUckvqwLD4LqRynaTFa/5Hs7sApa3/2aRDGrH080vTDzQFiILKSswLyPw09K59GBb2rr9Ouzg352npSE7sRexHKIcGFqd4MCl0Pj8zqX34hAcL3lPJ6TZjemWCTRgEB59HPczIGVNwdjb4xzpKucCqKjegIpvFhjzmltaUM7aEAN+g9cP/m13MQ92x/wmKgUDwu+2MEZnSA5KkNGEzQJYQmFWkBWmYqAdLpnM=&ddlFloor=2&txtUserName=test&txtPassword=1234&btnSubmit.x=15&btnSubmit.y=3";
byte[] buf = new byte[1024];
string header = sPost;
var client = new TcpClient();
client.Connect("182.50.132.48", 80);
// send request
var stream = client.GetStream();
var streamReader = new StreamReader(stream);
var streamWriter = new StreamWriter(stream);
streamWriter.Write(header);
streamWriter.Flush();
stream.Flush();
// get response
var response1 = streamReader.ReadLine();
302 is not an error. It is a request for redirection - the form tells you "go there instead", most likely as a result of your login attempt. WebClient handles the redirection, your client doesn't.
There's a lot of HTTP to implement. Unless this is purely an excercise, don't try to write your own HTTP client. Redirection is just the top of the iceberg.

Textfree Login Authentication Failing

I am trying to create a C# application that logs in to a Pinger Textfree account and can send SMS messages from it. The web version of this service is flash-based so I have been using Fiddler and Wireshark to monitor the HTTP requests that it uses. I have written some code that I think should log in but I get a "Bad Credentials" response from the server, however, I do know that the username and password I am using are accurate. I am also pretty sure that they do not append anything extra to either as I would have seen this in Fiddler.
static void Main(string[] args)
{
// Connect as client to port 443
string server = "api.pinger.com";
TcpClient client = new TcpClient(server, 443);
// Create a secure stream
using (SslStream sslStream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
{
sslStream.AuthenticateAsClient(server);
byte[] data = System.Text.Encoding.ASCII.GetBytes("POST https://api.pinger.com/1.0/web/login HTTP/1.1\r\n" +
"Host: api.pinger.com\r\n" +
"Connection: keep-alive\r\n" +
"Origin: http://pinger.com\r\n" +
"X-Rest-Method: POST\r\n" +
"Authorization: OAuth realm=\"https://api.pinger.com\", oauth_consumer_key=\"textfree-in-flash-web-free\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"HNN8gdLdskKnrtK2jbyN68b9JWQ%3D\", oauth_timestamp=\"1406102776\", oauth_nonce=\"635733471764340000\"\r\n" +
"Content-Type: application/json\r\n" +
"Accept: */*\r\n" +
"Referer: http://pinger.com/tfw/textFree_web.swf\r\n" +
"Accept-Encoding: gzip,deflate,sdch\r\n" +
"Accept-Language: en-US,en;q=0.8\r\n\r\n" +
//json info
"{\"password\":\"testing\",\"username\":\"myquestion\",\"clientId\":\"textfree-in-flash-web-free-1406143265-10D066F9-8126-CD00-4C3D-64AB7BA4FF52\"}\r\n"
);
sslStream.Write(data);
data = new byte[client.ReceiveBufferSize];
int bytesRead = -1;
do
{
bytesRead = sslStream.Read(data, 0, data.Length);
using (MemoryStream ms = new MemoryStream(data, 0, bytesRead))
using (StreamReader rd = new StreamReader(ms))
{
string returnData = rd.ReadToEnd();
Console.WriteLine(returnData);
}
} while (bytesRead != 0);
Console.ReadKey();
}
}
PS I created the account with these credentials (User: myquestion, Pass: testing) just for this question so they are correct and it should be working.
I am using the headers and formatting that the requests I recorded with Fiddler used.
My guesses as to why this attempt has failed is that I am either not posting the json correctly or the authorization header is incorrect or its the "clientId" key in the json. I have done a lot of trial and error as well as research and any help would be appreciated.

Amazon s3 C# auth

I need help with aws s3 Rest auth.
I have the next code:
string url = "http://fxstestcandles.cloudapp.net/pairs/history/eurusd";
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
WebHeaderCollection headers = (request as HttpWebRequest).Headers;
string httpDate = DateTime.UtcNow.ToString("ddd, dd MMM yyyy HH:mm:ss ") + "+0000";
string canonicalString = "GET\n\n\n " + httpDate + "\n/";
Encoding ae = new UTF8Encoding();
HMACSHA1 signature = new HMACSHA1();
signature.Key = ae.GetBytes("551a656b548e8466f555d540156b5a");
byte[] bytes = ae.GetBytes(canonicalString);
byte[] moreBytes = signature.ComputeHash(bytes);
string encodedCanonical = Convert.ToBase64String(moreBytes);
headers.Add("Authorization", "AWS " + "25496a25b6554f54b5e6" + ":" + encodedCanonical);
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
Stream stream = response.GetResponseStream() as Stream;
byte[] buffer = new byte[32 * 1024];
int nRead =0;
MemoryStream ms = new MemoryStream();
do
{
nRead = stream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, nRead);
} while (nRead > 0);
ASCIIEncoding encoding = new ASCIIEncoding();
string responseString = encoding.GetString(ms.ToArray());
System.Console.Write(responseString);
I need help i'm geeting the next error: (403) Forbiden.
The authentication is done following the steps on this link:
http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html.
The credentials are:
PublicKey: 25496a25b6554f54b5e6
PrivateKey: 551a656b548e8466f555d540156b5a
You just need to use the date for the SHA1, there is no need to use the entire the request string.
Example headers:
Date: Mon, 26 Mar 2007 19:37:58 +0000
Authorization: FXST AKIAIOSFODNN7EXAMPLE:frJIUN8DYpKDtOLCwo//yllqDzg=
Your problem seems to be your canonicalString and your HttpWebRequest , I had the same problem, please see the solution in this post: Amazon S3 REST API 403 error c#
That's sad how Amazon API is badly documented

Downloading file from URL with no extension in C#

I'm trying to get the zip file out of this link with C#:
http://dl.opensubtitles.org/en/download/sub/4860863
I've tried:
string ResponseText;
HttpWebRequest m = (HttpWebRequest)WebRequest.Create(o.link);
m.Method = WebRequestMethods.Http.Get;
using (HttpWebResponse response = (HttpWebResponse)m.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
ResponseText = reader.ReadToEnd();
// ResponseText = HttpUtility.HtmlDecode(ResponseText);
XmlTextReader xmlr = new XmlTextReader(new StringReader(ResponseText));
}
}
and
WebRequest request = WebRequest.Create(o.link);
using (WebResponse response = request.GetResponse())
using (Stream stream = response.GetResponseStream())
{
string contentType = response.ContentType;
// TODO: examine the content type and decide how to name your file
string filename = "test.zip";
// Download the file
using (Stream file = File.OpenWrite(filename))
{
// Remark: if the file is very big read it in chunks
// to avoid loading it into memory
byte[] buffer = new byte[response.ContentLength];
stream.Read(buffer, 0, buffer.Length);
file.Write(buffer, 0, buffer.Length);
}
}
But they all return something weird, nothing that looks like the file I need...
I think the link is php generated, but I'm not sure...
The opensubtitles api is no option for me...
Many thanks
It seems the Content-Type response is ok for me for your link:
Request URL:http://dl.opensubtitles.org/en/download/sub/4860863
Request Method:GET
Status Code:200 OK
Request Headersview:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*//*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:PHPSESSID=gk86hdrce96pu06kuajtue45a6; ts=1372177758
Host:dl.opensubtitles.org
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Response Headersview:
Accept-Ranges:bytes
Age:0
Cache-Control:must-revalidate, post-check=0, pre-check=0
Connection:keep-alive
Content-Disposition:attachment; filename="the.dark.knight.(2008).dut.1cd.(4860863).zip"
Content-Length:48473
Content-Transfer-Encoding:Binary
Content-Type:application/zip
Date:Tue, 25 Jun 2013 16:29:45 GMT
Expires:Mon, 1 Apr 2006 01:23:45 GMT
Pragma:public
Set-Cookie:ts=1372177785; expires=Thu, 25-Jul-2013 16:29:45 GMT; path=/
X-Cache:MISS
X-Cache-Backend:web1
I have check your code and test it using the link and the manual download produced a 48473 bytes file, and using your code produced 48564 bytes with zero after 0xDC2 and when I compared it with Hex editor, it have many different part. We may need to put more request header before sending the request.
ok, now i can resolve it: put cookie and read at a smaller chunk
private void button1_Click(object sender, EventArgs e) {
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("http://dl.opensubtitles.org/en/download/sub/4860863"));
//request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36";
//request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*//*;q=0.8";
//request.Headers["Accept-Encoding"] = "gzip,deflate,sdch";
request.Headers["Cookie"] = "PHPSESSID=gk86hdrce96pu06kuajtue45a6; ts=1372177758";
using (WebResponse response = request.GetResponse())
using (Stream stream = response.GetResponseStream()) {
string contentType = response.ContentType;
// TODO: examine the content type and decide how to name your file
string filename = "test.zip";
// Download the file
using (Stream file = File.OpenWrite(filename)) {
byte[] buffer = ReadFully(stream, 256);
stream.Read(buffer, 0, buffer.Length);
file.Write(buffer, 0, buffer.Length);
}
}
}
/// <summary>
/// Reads data from a stream until the end is reached. The
/// data is returned as a byte array. An IOException is
/// thrown if any of the underlying IO calls fail.
/// </summary>
/// <param name="stream">The stream to read data from</param>
/// <param name="initialLength">The initial buffer length</param>
public static byte[] ReadFully(Stream stream, int initialLength) {
// If we've been passed an unhelpful initial length, just
// use 32K.
if (initialLength < 1) {
initialLength = 32768;
}
byte[] buffer = new byte[initialLength];
int read = 0;
int chunk;
while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0) {
read += chunk;
// If we've reached the end of our buffer, check to see if there's
// any more information
if (read == buffer.Length) {
int nextByte = stream.ReadByte();
// End of stream? If so, we're done
if (nextByte == -1) {
return buffer;
}
// Nope. Resize the buffer, put in the byte we've just
// read, and continue
byte[] newBuffer = new byte[buffer.Length * 2];
Array.Copy(buffer, newBuffer, buffer.Length);
newBuffer[read] = (byte)nextByte;
buffer = newBuffer;
read++;
}
}
// Buffer is now too big. Shrink it.
byte[] ret = new byte[read];
Array.Copy(buffer, ret, read);
return ret;
}
EDIT: You don't need to set Cookie at all, you'll produce a different file but a valid one. I assume the server add extra info to the file when you revisit them.

Can't upload a photo to Appcelerator Cloud Service using HttpWebRequest in C#

I'm developing an application in C# that connects to Appcelerator Cloud Service, so far I can make queries and create custom objects, now the problem is when I try to create a photo in ACS. I looked at this link and modified my code like this:
Image img = pbPhoto.Image;
img.Save(Application.StartupPath + "\\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg); //saving the image temporally in hard drive
url = "https://api.cloud.appcelerator.com/v1/photos/create.json?key=appkey&_session_id=" + session;
HttpWebRequest wrGetUrl = (HttpWebRequest)WebRequest.Create(url);
String boundary = "B0unD-Ary";
wrGetUrl.ContentType = "multipart/form-data; boundary=" + boundary;
wrGetUrl.Method = "POST";
String postData = "--" + boundary + "\nContent-Disposition: form-data\n\n";;
postData += "\n--" + boundary + "\nContent-Disposition: form-data; name=\"file\" filename=\"" + Application.StartupPath + "\\tmp.jpg" + "\"\nContent-Type: image/jpeg\n\n";
byteArray = Encoding.UTF8.GetBytes(postData);
byte[] filedata = null;
using (BinaryReader readerr = new BinaryReader(File.OpenRead(Application.StartupPath + "\\tmp.jpg")))
filedata = readerr.ReadBytes((int)readerr.BaseStream.Length);
wrGetUrl.ContentLength = byteArray.Length + filedata.Length;
wrGetUrl.GetRequestStream().Write(byteArray, 0, byteArray.Length);
wrGetUrl.GetRequestStream().Write(filedata, 0, filedata.Length);
objStream = wrGetUrl.GetResponse().GetResponseStream();
reader = new StreamReader(objStream);
I tried this but I got the following error
The remote server returned an error: (500) Internal Server Error.
I checked my ACS log but the request didn't show up (guess because it was a 500 error). What should I change in my code to upload the photo and crete the photo in ACS? Thanks for any help you may give.
Found the solution for this problem:
byte[] filedata = null;
using (BinaryReader readerr = new BinaryReader(File.OpenRead(pathToImage)))
filedata = readerr.ReadBytes((int)readerr.BaseStream.Length);
string boundary = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
Stream stream = request.GetRequestStream();
request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
StreamWriter writer = new StreamWriter(stream);
writer.Write("--");
writer.WriteLine(boundary);
writer.WriteLine(#"Content-Disposition: form-data; name=""{0}""; filename=""{1}""", "your_name", "your_photo_file_name");
writer.WriteLine(#"Content-Type: application/octet-stream");
writer.WriteLine(#"Content-Length: " + filedata .Length);
writer.WriteLine();
writer.Flush();
Stream output = writer.BaseStream;
output.Write(filedata , 0, filedata .Length);
output.Flush();
writer.WriteLine();
writer.Write("--");
writer.Write(boundary);
writer.WriteLine("--");
writer.Flush();
EDIT: I changed the way I wrote the headers into the RequestStream, the way I was writing it wasn't the proper one to send a picture to Appcelerator Cloud Service, by sending requests through curl and checking the Log in ACS I was able to come up with the right headers.
Hope this may help anyone with similar problems.

Categories