Download binary file over HTTP - c#

I need to download a binary file , uploaded via http post. I can not able to download file.
I can see the content of data but I'm not able to save into my local disk.
this is what i see in string
--fUYxo2BFe6N Content-Disposition: form-data; name="data"; filename="EVLD_1.4.36_16_0993_0_000AAE0E0109_2D8A145A040000CC_0E0B1B0F3B29_0008.akt" Content-Type: application/x-gzip
‹ òÖwTcÈ”cdäã–æ7´fàZÇÇÈÉÀÀüA Èåp’Y9,Lp%ì#1& ‹…Äg¬ ‚
,
"8€dÐDÁ
"x#/ˆàü B D‚!!Ä ƒ³e¹!ê™è›è˜™ƒ‘e+R9*ÌG[+‚´möÛÊ€äò0²ª2¬B† --fUYxo2BFe6N Content-Disposition: form-data; name="SehirID"
16 --fUYxo2BFe6N Content-Disposition: form-data; name="CihazTipiID"
64 --fUYxo2BFe6N Content-Disposition: form-data; name="CihazAltTipiID"
1 --fUYxo2BFe6N Content-Disposition: form-data; name="md5"
1FAFE4C67252889C75C526EA4313BE27 --fUYxo2BFe6N Content-Disposition: form-data; name="mac"
000AAE0E0109 --fUYxo2BFe6N--
This is my source code for listenint requests. I can handle de requests but I'm not able to save content into a file..
public class HttpProcessor
{
public TcpClient socket;
public HttpServer srv;
private Stream inputStream;
public StreamWriter outputStream;
public String http_method;
public String http_url;
public String http_protocol_versionstring;
public Hashtable httpHeaders = new Hashtable();
private static int MAX_POST_SIZE = 10 * 1024 * 1024; // 10MB
public HttpProcessor(TcpClient s, HttpServer srv)
{
this.socket = s;
this.srv = srv;
}
private string streamReadLine(Stream inputStream)
{
int next_char;
string data = "";
while (true)
{
next_char = inputStream.ReadByte();
if (next_char == '\n') { break; }
if (next_char == '\r') { continue; }
if (next_char == -1) { Thread.Sleep(1); continue; };
data += Convert.ToChar(next_char);
}
return data;
}
public void process()
{
// we can't use a StreamReader for input, because it buffers up extra data on us inside it's
// "processed" view of the world, and we want the data raw after the headers
inputStream = new BufferedStream(socket.GetStream());
// we probably shouldn't be using a streamwriter for all output from handlers either
outputStream = new StreamWriter(new BufferedStream(socket.GetStream()));
try
{
parseRequest();
readHeaders();
if (http_method.Equals("GET"))
{
handleGETRequest();
}
else if (http_method.Equals("POST"))
{
handlePOSTRequest();
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.ToString());
writeFailure();
}
outputStream.Flush();
// bs.Flush(); // flush any remaining output
inputStream = null; outputStream = null; // bs = null;
socket.Close();
}
public void parseRequest()
{
String request = streamReadLine(inputStream);
string[] tokens = request.Split(' ');
if (tokens.Length != 3)
{
throw new Exception("invalid http request line");
}
http_method = tokens[0].ToUpper();
http_url = tokens[1];
http_protocol_versionstring = tokens[2];
Console.WriteLine("starting: " + request);
}
public void readHeaders()
{
Console.WriteLine("readHeaders()");
String line;
while ((line = streamReadLine(inputStream)) != null)
{
if (line.Equals(""))
{
Console.WriteLine("got headers");
return;
}
int separator = line.IndexOf(':');
if (separator == -1)
{
throw new Exception("invalid http header line: " + line);
}
String name = line.Substring(0, separator);
int pos = separator + 1;
while ((pos < line.Length) && (line[pos] == ' '))
{
pos++; // strip any spaces
}
string value = line.Substring(pos, line.Length - pos);
Console.WriteLine("header: {0}:{1}", name, value);
httpHeaders[name] = value;
}
}
public void handleGETRequest()
{
srv.handleGETRequest(this);
}
private const int BUF_SIZE = 4096;
public void handlePOSTRequest()
{
// this post data processing just reads everything into a memory stream.
// this is fine for smallish things, but for large stuff we should really
// hand an input stream to the request processor. However, the input stream
// we hand him needs to let him see the "end of the stream" at this content
// length, because otherwise he won't know when he's seen it all!
Console.WriteLine("get post data start");
int content_len = 0;
MemoryStream ms = new MemoryStream();
if (this.httpHeaders.ContainsKey("Content-Length"))
{
content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]);
if (content_len > MAX_POST_SIZE)
{
throw new Exception(
String.Format("POST Content-Length({0}) too big for this simple server",
content_len));
}
byte[] buf = new byte[BUF_SIZE];
int to_read = content_len;
while (to_read > 0)
{
Console.WriteLine("starting Read, to_read={0}", to_read);
int numread = this.inputStream.Read(buf, 0, Math.Min(BUF_SIZE, to_read));
Console.WriteLine("read finished, numread={0}", numread);
if (numread == 0)
{
if (to_read == 0)
{
break;
}
else
{
throw new Exception("client disconnected during post");
}
}
to_read -= numread;
ms.Write(buf, 0, numread);
}
ms.Seek(0, SeekOrigin.Begin);
// String s1 = Encoding.UTF8.GetString(ms.ToArray());
}
Console.WriteLine("get post data end");
srv.handlePOSTRequest(this, new StreamReader(ms));
}
private static Stream GetPostStream(string filePath, string boundary)
{
Stream postDataStream = new System.IO.MemoryStream();
//adding form data
string formDataHeaderTemplate = Environment.NewLine + "--" + boundary + Environment.NewLine +
"Content-Disposition: form-data; name=\"{0}\";" + Environment.NewLine + Environment.NewLine + "{1}";
//foreach (string key in formData.Keys)
//{
// byte[] formItemBytes = System.Text.Encoding.UTF8.GetBytes(string.Format(formDataHeaderTemplate,
// key, formData[key]));
// postDataStream.Write(formItemBytes, 0, formItemBytes.Length);
//}
//adding file data
FileInfo fileInfo = new FileInfo(filePath);
string fileHeaderTemplate = Environment.NewLine + "--" + boundary + Environment.NewLine +
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" +
Environment.NewLine + "Content-Type: application/vnd.ms-excel" + Environment.NewLine + Environment.NewLine;
byte[] fileHeaderBytes = System.Text.Encoding.UTF8.GetBytes(string.Format(fileHeaderTemplate,
"UploadCSVFile", fileInfo.FullName));
postDataStream.Write(fileHeaderBytes, 0, fileHeaderBytes.Length);
FileStream fileStream = fileInfo.OpenRead();
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
postDataStream.Write(buffer, 0, bytesRead);
}
fileStream.Close();
byte[] endBoundaryBytes = System.Text.Encoding.UTF8.GetBytes("--" + boundary + "--");
postDataStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
return postDataStream;
}
public void writeSuccess(string content_type = "text/html")
{
outputStream.WriteLine("HTTP/1.0 200 OK");
outputStream.WriteLine("Content-Type: " + content_type);
outputStream.WriteLine("Connection: close");
outputStream.WriteLine("");
}
public void writeFailure()
{
outputStream.WriteLine("HTTP/1.0 404 File not found");
outputStream.WriteLine("Connection: close");
outputStream.WriteLine("");
}
}
public abstract class HttpServer
{
protected int port;
TcpListener listener;
bool is_active = true;
public HttpServer(int port)
{
this.port = port;
}
public void listen()
{
listener = new TcpListener(port);
listener.Start();
while (is_active)
{
TcpClient s = listener.AcceptTcpClient();
HttpProcessor processor = new HttpProcessor(s, this);
Thread thread = new Thread(new ThreadStart(processor.process));
thread.Start();
Thread.Sleep(1);
}
}
public abstract void handleGETRequest(HttpProcessor p);
public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData);
}
public class MyHttpServer : HttpServer
{
public MyHttpServer(int port)
: base(port)
{
}
public override void handleGETRequest(HttpProcessor p)
{
if (p.http_url.Equals("/Test.png"))
{
Stream fs = File.Open("../../Test.png", FileMode.Open);
p.writeSuccess("image/png");
fs.CopyTo(p.outputStream.BaseStream);
p.outputStream.BaseStream.Flush();
}
Console.WriteLine("request: {0}", p.http_url);
p.writeSuccess();
p.outputStream.WriteLine("<html><body><h1>test server</h1>");
p.outputStream.WriteLine("Current Time: " + DateTime.Now.ToString());
p.outputStream.WriteLine("url : {0}", p.http_url);
p.outputStream.WriteLine("<form method=post action=/form>");
p.outputStream.WriteLine("<input type=text name=foo value=foovalue>");
p.outputStream.WriteLine("<input type=submit name=bar value=barvalue>");
p.outputStream.WriteLine("</form>");
}
public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData)
{
Console.WriteLine("POST request: {0}", p.http_url);
string data = inputData.ReadToEnd();
//SaveStreamToFile(inputData);
p.writeSuccess();
p.outputStream.WriteLine("<html><body><h1>test server</h1>");
p.outputStream.WriteLine("<a href=/test>return</a><p>");
p.outputStream.WriteLine("postbody: <pre>{0}</pre>", data);
}
public void SaveStreamToFile(Stream stream)
{
if (stream.Length == 0) return;
// Create a FileStream object to write a stream to a file
using (FileStream fileStream = System.IO.File.Create(#"C:/EmreDenemeHttp.txt", (int)stream.Length))
{
// Fill the bytes[] array with the stream data
byte[] bytesInStream = new byte[stream.Length];
stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
// Use FileStream object to write to the specified file
fileStream.Write(bytesInStream, 0, bytesInStream.Length);
}
}
}
public class TestMain
{
public static int Main(String[] args)
{
HttpServer httpServer;
if (args.GetLength(0) > 0)
{
httpServer = new MyHttpServer(Convert.ToInt16(args[0]));
}
else
{
httpServer = new MyHttpServer(80);
}
Thread thread = new Thread(new ThreadStart(httpServer.listen));
thread.Start();
return 0;
}
}

If you mean you see this as string in your browser, the mime type sent by your server to your client may be wrong.
By default it is set to text/html.
It should be something like application/x-binary
or perhaps application/x-gzip
Check what mime type is fetched by your client when you display the page and act accordingly on your server.

Related

Upload files using Web API and Windows application in .Net

I need to upload files from client machine to a remote server and for that i have created a windows application which will work as client. It will select the required file and call the Web API.
Please find my client code as below :
//...other code removed for brevity
private void UploadFile(string filename)
{
Stream ms = new MemoryStream();
using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
var fileInfo = new FileInfo(filename);
byte[] bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
ms.Write(bytes, 0, (int)file.Length);
MultiPartFormUpload multiPartFormUpload = new MultiPartFormUpload();
List<FileInfo> files = new List<FileInfo>() { fileInfo };
try
{
MultiPartFormUpload.UploadResponse response = multiPartFormUpload.Upload("http://localhost:10458/api/Upload", files);
}
catch (Exception ex)
{
throw ex;
}
}
}
public class MultiPartFormUpload
{
public class MimePart
{
NameValueCollection _headers = new NameValueCollection();
byte[] _header;
public NameValueCollection Headers
{
get { return _headers; }
}
public byte[] Header
{
get { return _header; }
}
public long GenerateHeaderFooterData(string boundary)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("--");
stringBuilder.Append(boundary);
stringBuilder.AppendLine();
foreach (string key in _headers.AllKeys)
{
stringBuilder.Append(key);
stringBuilder.Append(": ");
stringBuilder.AppendLine(_headers[key]);
}
stringBuilder.AppendLine();
_header = Encoding.UTF8.GetBytes(stringBuilder.ToString());
return _header.Length + Data.Length + 2;
}
public Stream Data { get; set; }
}
public class UploadResponse
{
public UploadResponse(HttpStatusCode httpStatusCode, string responseBody)
{
HttpStatusCode = httpStatusCode;
ResponseBody = responseBody;
}
public HttpStatusCode HttpStatusCode { get; set; }
public string ResponseBody { get; set; }
}
public UploadResponse Upload(string url, List<FileInfo> files)
{
using (WebClient client = new WebClient())
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (FileInfo file in files)
{
MimePart part = new MimePart();
string name = file.Extension.Substring(1);
string fileName = file.Name;
part.Headers["Content-Disposition"] = "form-data; name=\"" + name + "\"; filename=\"" + fileName + "\"";
part.Headers["Content-Type"] = "application/octet-stream";
part.Data = new MemoryStream(File.ReadAllBytes(file.FullName));
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
client.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart mimePart in mimeParts)
{
contentLength += mimePart.GenerateHeaderFooterData(boundary);
}
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
using (MemoryStream memoryStream = new MemoryStream())
{
foreach (MimePart mimePart in mimeParts)
{
memoryStream.Write(mimePart.Header, 0, mimePart.Header.Length);
while ((read = mimePart.Data.Read(buffer, 0, buffer.Length)) > 0)
memoryStream.Write(buffer, 0, read);
mimePart.Data.Dispose();
memoryStream.Write(afterFile, 0, afterFile.Length);
}
memoryStream.Write(_footer, 0, _footer.Length);
byte[] responseBytes = client.UploadData(url, memoryStream.ToArray());
string responseString = Encoding.UTF8.GetString(responseBytes);
return new UploadResponse(HttpStatusCode.OK, responseString);
}
}
catch (Exception ex)
{
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
if (ex.GetType().Name == "WebException")
{
WebException webException = (WebException)ex;
HttpWebResponse response = (HttpWebResponse)webException.Response;
string responseString;
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
responseString = reader.ReadToEnd();
}
return new UploadResponse(response.StatusCode, responseString);
}
else
{
throw;
}
}
}
}
}
Please find Web API code as below :
public async Task<HttpResponseMessage> Post()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string fileSaveLocation = HttpContext.Current.Server.MapPath("~/upload/files");
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
List<string> files = new List<string>();
try
{
await Request.Content.ReadAsMultipartAsync(provider);
foreach (MultipartFileData file in provider.FileData)
{
files.Add(Path.GetFileName(file.LocalFileName));
}
// Send OK Response along with saved file names to the client.
return Request.CreateResponse(HttpStatusCode.OK, files);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public CustomMultipartFormDataStreamProvider(string path) : base(path) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
}
}
I am able to hit the Web API with the client code but fileInfo.Length is coming 0.
Please let me know what i am missing in Client or Web API code. Thanks !

JS: Call API from server side

The following JavaScript code is working fine on old i9 browser but not on the latest one. Now I want to call API from server side as this code is not working due to cross domain cores issue.
var xmlHttpDevice = new XMLHttpRequest();
xmlHttpDevice.open("DEVICEINFO", "http://127.0.0.1:" + PortNumber + "/getDeviceInfo", true);
xmlHttpDevice.onload = function (e) {
if (xmlHttpDevice.readyState === 4) {
if (xmlHttpDevice.status === 200) {
alert(xmlHttpDevice.responseText);
} else {
alert(xmlHttpDevice.statusText);
}
}
};
xmlHttpDevice.onerror = function (e) {
console.error(xmlHttpDevice.statusText);
};
var params = "rdverb=DEVICEINFO&URL=''";
xmlHttpDevice.send(params);
my server side code :
TcpClient socket = new TcpClient();
try
{
// Call EndGetContext to complete the asynchronous operation.
HttpListenerContext context = listener.EndGetContext(result);
HttpListenerRequest request = context.Request;
string strPortNumber = string.Empty;
string strRDVerb = "";
int PortNumberStartRange = 11099;
result.AsyncWaitHandle.WaitOne();
if (context.Request.InputStream != null)
{
var body = new StreamReader(context.Request.InputStream).ReadToEnd();
GetPostedData(ref strPortNumber, ref strRDVerb, body);
}
else
{
strPortNumber = "12345";
strRDVerb = "RDSERVICE";
}
if (strRDVerb != "RDSERVICE" && strRDVerb != "DEVICEINFO")
{
strRDVerb = "CAPTURE";
}
//var body = new StreamReader(context.Request.InputStream).ReadToEnd();
string response = string.Empty;
//Get the stream that will be used to send/receive data
ExecuteRecoveryCode(ref socket, PortNumberStartRange);
NetworkStream ns = socket.GetStream();
//Write the HTTP Header info to the stream
StreamWriter sw = new StreamWriter(ns);
if (strRDVerb == "DEVICEINFO")
{
var message = "rdverb=DEVICEINFO&URL=''";
//var data = System.Text.Encoding.ASCII.GetBytes(message);
sw.Write(message, 0, message.Length);
sw.WriteLine(string.Format(strRDVerb + " /getDeviceInfo HTTP/1.1"));
sw.WriteLine(string.Format("HOST:127.0.0.1:11100"));
}
sw.Flush();
//Save the data that lives in the stream
string packet = string.Empty;
StreamReader sr = new StreamReader(ns);
int count = 0;
string EndString = string.Empty;
GetServiceMethod(strRDVerb, ref count, ref EndString);
for (int i = 0; i < count; i++)
{
packet = sr.ReadLine();
response += packet;
}
HttpListenerResponse resp = context.Response;
//byte[] buffer = System.Text.Encoding.UTF8.GetBytes("<HTML><BODY> " + response + EndString + "</BODY></HTML>");
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(response + EndString);
resp.StatusDescription = response;
resp.ContentLength64 = buffer.Length;
System.IO.Stream output = resp.OutputStream;
resp.StatusCode = (int)HttpStatusCode.OK;
output.Write(buffer, 0, buffer.Length);
output.Close();
resp.Close();
}
catch (Exception ex)
{
//throw ex;
}
finally
{
socket.Close();
listener.BeginGetContext(new AsyncCallback(OnRequestReceive), listener);
}

How can I save http requests from applications in c#?

When I connect my phone to iTunes it sends a request to a certain server so I have managed to divert to my server which I think I don't have the file or files that iTunes asks for but I would like to know what iTunes is requesting.
Here is my code
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;
using System.Collections.Generic;
using System.IO;
namespace SimpleWebServer
{
class Server
{
/************************************\
* Acrobyte Http Web Server *
* Alexio Puk2sefu *
* www.acrobytemob.com *
* Alexiopuk2sefu#acrobytemob.com *
\************************************/
public bool running = false; // Is it running?
private int timeout = 8; // Time limit for data transfers.
private Encoding charEncoder = Encoding.UTF8; // To encode string
private Socket serverSocket; // Our server socket
private string contentPath; // Root path of our contents
// Content types that are supported by our server
// You can add more...
// To see other types: http://www.webmaster-toolkit.com/mime-types.shtml
private Dictionary<string, string> extensions = new Dictionary<string, string>()
{
//{ "extension", "content type" }
{ "htm", "text/html" },
{ "html", "text/html" },
{ "xml", "text/xml" },
{ "txt", "text/plain" },
{ "css", "text/css" },
{ "png", "image/png" },
{ "gif", "image/gif" },
{ "jpg", "image/jpg" },
{ "jpeg", "image/jpeg" },
{ "zip", "application/zip"},
{ "plist", "application/plist"},
{ "app", "application/app"},
{ "file", "application/file"}
};
public bool start(IPAddress ipAddress, int port, int maxNOfCon, string contentPath)
{
if (running) return false; // If it is already running, exit.
try
{
// A tcp/ip socket (ipv4)
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(ipAddress, port));
serverSocket.Listen(maxNOfCon);
serverSocket.ReceiveTimeout = timeout;
serverSocket.SendTimeout = timeout;
running = true;
this.contentPath = contentPath;
}
catch { return false; }
// Our thread that will listen connection requests and create new threads to handle them.
Thread requestListenerT = new Thread(() =>
{
while (running)
{
Socket clientSocket;
try
{
clientSocket = serverSocket.Accept();
// Create new thread to handle the request and continue to listen the socket.
Thread requestHandler = new Thread(() =>
{
clientSocket.ReceiveTimeout = timeout;
clientSocket.SendTimeout = timeout;
try { handleTheRequest(clientSocket); }
catch
{
try { clientSocket.Close(); } catch { }
}
});
requestHandler.Start();
}
catch{}
}
});
requestListenerT.Start();
return true;
}
public void stop()
{
if (running)
{
running = false;
try { serverSocket.Close(); }
catch { }
serverSocket = null;
}
}
private void handleTheRequest(Socket clientSocket)
{
byte[] buffer = new byte[10240]; // 10 kb, just in case
int receivedBCount = clientSocket.Receive(buffer); // Receive the request
string strReceived = charEncoder.GetString(buffer, 0, receivedBCount);
// Parse the method of the request
string httpMethod = strReceived.Substring(0, strReceived.IndexOf(" "));
int start = strReceived.IndexOf(httpMethod) + httpMethod.Length + 1;
int length = strReceived.LastIndexOf("HTTP") - start - 1;
string requestedUrl = strReceived.Substring(start, length);
string requestedFile;
if (httpMethod.Equals("GET") || httpMethod.Equals("POST"))
requestedFile = requestedUrl.Split('?')[0];
else // You can implement other methods...
{
notImplemented(clientSocket);
return;
}
requestedFile = requestedFile.Replace("/", "\\").Replace("\\..", ""); // Not to go back
start = requestedFile.LastIndexOf('.') + 1;
if (start > 0)
{
length = requestedFile.Length - start;
string extension = requestedFile.Substring(start, length);
if (extensions.ContainsKey(extension)) // Do we support this extension?
if (File.Exists(contentPath + requestedFile)) // If yes check existence
// Everything is OK, send requested file with correct content type:
sendOkResponse(clientSocket, File.ReadAllBytes(contentPath + requestedFile), extensions[extension]);
else
notFound(clientSocket); // We don't support this extension. We are assuming that it doesn't exist.
}
else
{
// If file is not specified try to send index.htm or index.html
// You can add more (for example "default.html")
if (requestedFile.Substring(length - 1, 1) != "\\")
requestedFile += "\\";
if (File.Exists(contentPath + requestedFile + "index.htm"))
sendOkResponse(clientSocket, File.ReadAllBytes(contentPath + requestedFile + "\\index.htm"), "text/html");
else if (File.Exists(contentPath + requestedFile + "index.html"))
sendOkResponse(clientSocket, File.ReadAllBytes(contentPath + requestedFile + "\\index.html"), "text/html");
else
notFound(clientSocket);
}
}
private void notImplemented(Socket clientSocket)
{
sendResponse(clientSocket, "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body><h2>Atasoy Simple Web Server</h2><div>501 - Method Not Implemented</div></body></html>", "501 Not Implemented", "text/html");
}
private void notFound(Socket clientSocket)
{
sendResponse(clientSocket, "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"></head><body><h2>Atasoy Simple Web Server</h2><div>404 - Not Found</div></body></html>", "404 Not Found", "text/html");
}
private void sendOkResponse(Socket clientSocket, byte[] bContent, string contentType)
{
sendResponse(clientSocket, bContent, "200 OK", contentType);
}
// For strings
private void sendResponse(Socket clientSocket, string strContent, string responseCode, string contentType)
{
byte[] bContent = charEncoder.GetBytes(strContent);
sendResponse(clientSocket, bContent, responseCode, contentType);
}
// For byte arrays
private void sendResponse(Socket clientSocket, byte[] bContent, string responseCode, string contentType)
{
try
{
byte[] bHeader = charEncoder.GetBytes(
"HTTP/1.1 " + responseCode + "\r\n"
+ "Server: Acrobyte Web Server\r\n"
+ "Content-Length: " + bContent.Length.ToString() + "\r\n"
+ "Connection: close\r\n"
+ "Content-Type: " + contentType + "\r\n\r\n");
clientSocket.Send(bHeader);
clientSocket.Send(bContent);
clientSocket.Close();
}
catch { }
}
}
}
So the request is coming to this server but iTunes says error and I simply would like to save that request and view it later

Odd Memcached server behavior when reading data with a certain length

I wrote a simple couchbase/memcached client in C# and recently ran into some odd behavior with the couchbase server. If the length of the data plus key are between 1004-1008 characters the server adds an extra blank line to the end of the data. I was wondering if this was intended behavior or a bug? I have also tested this on a freshly installed memcached server on OSX and got the same result.
class Program
{
static void Main(string[] args)
{
char[] charArray = new char[959];
for (int x = 0; x < 959; x++)
{
charArray[x] = ' ';
}
string data = new string(charArray);
string key = Couchbase.kurogoKeyCode + "2090Event";
string json = String.Empty;
using (Couchbase.Client client = new Couchbase.Client())
{
client.Set(key, data, 0);
json = client.Read(key);
Console.WriteLine(json);
client.Read(key);
Console.WriteLine(json); // <-- This line outputs the header instead of the data b/c the streamreader is off a line
// I added and commented out a fix in the read method
}
}
}
public class Couchbase
{
public const string kurogoKeyCode = "51e2b57ace3c5364dd10a33e1f34a44c-XX-";
public class Client : IDisposable
{
private TcpClient tcpClient;
private NetworkStream networkStream;
private StreamReader streamReader;
private StreamWriter streamWriter;
public Client()
{
tcpClient = new TcpClient("127.0.0.1", 11211);
networkStream = tcpClient.GetStream();
streamReader = new StreamReader(networkStream);
streamWriter = new StreamWriter(networkStream);
networkStream.ReadTimeout = 200;
}
public bool Disconnect()
{
streamWriter.Write("quit\r\n");
streamWriter.Flush();
tcpClient.Close();
return true;
}
public void Dispose()
{
this.Disconnect();
GC.SuppressFinalize(this);
}
public string Read(string key)
{
try
{
streamWriter.WriteLine("get " + key);
streamWriter.Flush();
string header = streamReader.ReadLine();
if (header == null)
return String.Empty;
string json = streamReader.ReadLine();
streamReader.DiscardBufferedData();
//while (networkStream.DataAvailable)
// streamReader.ReadLine();
return json;
}
catch (System.IO.IOException)
{
return null;
}
}
public bool Set(string key, string value, int secondsToLive = 0)
{
string returnValue = String.Empty;
streamWriter.WriteLine("set " + key + " 0 " + secondsToLive + " " + value.Length);
streamWriter.Flush();
streamWriter.WriteLine(value);
streamWriter.Flush();
while (!networkStream.DataAvailable)
{
Thread.Sleep(25);
}
returnValue = streamReader.ReadLine();
if (returnValue == "STORED")
return true;
return false;
}
public bool Delete(string key)
{
string returnValue = String.Empty;
try
{
streamWriter.WriteLine("delete " + key);
streamWriter.Flush();
while (!networkStream.DataAvailable)
{
Thread.Sleep(25);
}
returnValue = streamReader.ReadLine();
if (returnValue == "DELETED")
return true;
return false;
}
catch
{
return false;
}
}
}
}

Downloading web site using sockets

I'm trying to download source of the site using sockets. Currently i can download headers and after that i just terminate connection because i don't know how long should I receive data. This is the code:
private void HandleConnect(SocketAsyncEventArgs e)
{
if (e.ConnectSocket != null)
{
// simply start sending
bool completesAsynchronously = e.ConnectSocket.SendAsync(e);
// check if the completed event will be raised.
// if not, invoke the handler manually.
if (!completesAsynchronously)
{
SocketAsyncEventArgs_Completed(e.ConnectSocket, e);
}
}
}
private void HandleReceive(SocketAsyncEventArgs e)
{
string responseL = Encoding.UTF8.GetString(e.Buffer, 0, e.Buffer.Length);
response += responseL;
temp += responseL;
string[] lines = Regex.Split(response, "\r\n\r\n");
if (lines.Length > 1 && header == "")
{
header = lines[0].ToString() + "\r\n";
lines[0] = "";
response = lines.ToString();
}
if (header == "")
{
bool completesAsynchronously = e.ConnectSocket.ReceiveAsync(e);
}
else
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(delegate()
{
_callback(false, this);
});
}
}
I was trying to search for \r\n but it didn't help :/
Please help!
Thank you in advance :)
I use this code to send headers to the site and then read its content. I hope you find it useful.
ReadStateObject stateObject; //Info below
mytcpclient = new TcpClient();
mytcpclient.Connect(host, port);
mysocket = mytcpclient.Client;
SendHeader(mysocket);//Info below
ns = mytcpclient.GetStream();
if (ns.CanRead)
{
stateObject = new ReadStateObject(ns, 1024);
ns.BeginRead(stateObject.ReadBuffer, 0, stateObject.ReadBuffer.Length, new AsyncCallback(ReadCallBack), stateObject);
}
StateObject is small class used to represent the AsyncState object in BeginRead method:
class ReadStateObject
{
public NetworkStream Stream {get; set;}
public byte[] ReadBuffer;
public ReadStateObject(NetworkStream _stream, int bufferSize)
{
Stream = _stream;
ReadBuffer = new byte[bufferSize];
}
}
And this is a Callback Method used in BeginRead method.
private void ReadCallBack(IAsyncResult result)
{
ReadStateObject stateObject = (ReadStateObject)result.AsyncState;
NetworkStream myNetworkStream = stateObject.Stream;
int numberofbytesread = 0;
StringBuilder sb = new StringBuilder();
numberofbytesread = myNetworkStream.EndRead(result);
sb.Append(Encoding.ASCII.GetString(stateObject.ReadBuffer, 0, numberofbytesread));
/*It seems, if there is no delay, the DataAvailable may not be true even when there are still data to be received from the site, so I added this delay. Any suggestions, how to avoid this are welcome*/
Thread.Sleep(500);
while (myNetworkStream.DataAvailable)
{
byte[] mydata = new byte[1024];
numberofbytesread = myNetworkStream.Read(mydata, 0, mydata.Length);
sb.Append(Encoding.ASCII.GetString(mydata, 0, numberofbytesread));
}
Console.Writeln(sb.ToString());
mytcpclient.Close();
}
And this is where Headers are sent to the site
public void SendHeader(Socket mySocket)
{
String sBuffer = "";
sBuffer = sBuffer + "GET /"+pathquery+" HTTP/1.1" + "\r\n";
sBuffer = sBuffer + "Host: "+ hostname + "\r\n";
sBuffer = sBuffer + "Content-Type: text/html\r\n";
sBuffer = sBuffer + "\r\n";
Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);
mySocket.Send(Encoding.ASCII.GetBytes(sBuffer), Encoding.ASCII.GetBytes(sBuffer).Length, 0);
}
Maybe, you should use WebClient or HttpWebRequest instead of sockets.
Using sockets and interpreting Http protocol can be painful.

Categories

Resources