Skip to content

Instantly share code, notes, and snippets.

@peppy
Created August 31, 2015 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peppy/cb502fa48631de0331e0 to your computer and use it in GitHub Desktop.
Save peppy/cb502fa48631de0331e0 to your computer and use it in GitHub Desktop.
Broken code (AddFile fails with byte[] around 50k or more)
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using Newtonsoft.Json;
namespace osu_common.Helpers
{
public class pWebRequest
{
public string Url;
internal bool Aborted { get; private set; }
public event RequestUpdateHandler Updated;
public event RequestCompleteHandler Finished;
public event RequestStartedHandler Started;
public Dictionary<string, object> Parameters = new Dictionary<string, object>();
public pWebRequest(string url, params object[] args)
{
if (args.Length == 0)
Url = url;
else
Url = string.Format(url, args);
}
private HttpWebRequest request;
public HttpWebRequest Request
{
get
{
if (request == null) request = CreateWebRequest();
return request;
}
}
public WebResponse Response;
Stream responseStream;
protected virtual HttpWebRequest CreateWebRequest()
{
return WebRequest.Create(Url) as HttpWebRequest;
}
private int BytesRead;
private int ContentLength;
const int buffer_size = 8192;
private byte[] buffer;
private MemoryStream bodyStream = new MemoryStream();
protected virtual Stream CreateOutputStream()
{
return new MemoryStream();
}
public Stream ResponseStream;
public string ResponseString
{
get
{
try
{
ResponseStream.Seek(0, SeekOrigin.Begin);
StreamReader r = new StreamReader(ResponseStream, Encoding.UTF8);
return r.ReadToEnd();
}
catch
{
return null;
}
}
}
public byte[] ResponseData
{
get
{
try
{
using (MemoryStream ms = new MemoryStream((int)ResponseStream.Length))
{
ResponseStream.Seek(0, SeekOrigin.Begin);
ResponseStream.CopyTo(ms);
return ms.ToArray();
}
}
catch
{
return null;
}
}
}
public virtual void Perform()
{
ResponseStream = CreateOutputStream();
Request.UserAgent = @"osu!";
Request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
if (Parameters.Count > 0)
{
string boundary = @"-----------------------------28947758029299";
Request.ContentType = string.Format(@"multipart/form-data; boundary={0}", boundary);
foreach (KeyValuePair<string, object> p in Parameters)
{
bodyStream.WriteLineExplicit("--" + boundary);
if (p.Value is byte[])
{
bodyStream.WriteLineExplicit("Content-Disposition: form-data; name=\"{0}\"; filename=\"{0}\"", p.Key);
bodyStream.WriteLineExplicit("Content-Type: application/octet-stream");
bodyStream.WriteLineExplicit();
byte[] data = (byte[])p.Value;
bodyStream.Write(data, 0, data.Length);
bodyStream.WriteLineExplicit();
bodyStream.WriteLineExplicit();
}
else
{
bodyStream.WriteLineExplicit("Content-Disposition: form-data; name=\"{0}\"", p.Key);
bodyStream.WriteLineExplicit();
bodyStream.WriteLineExplicit(p.Value);
bodyStream.WriteLineExplicit();
}
}
bodyStream.WriteLineExplicit("--" + boundary + "--");
bodyStream.Flush();
}
if (bodyStream.Length > 0)
{
//POST
Request.Method = @"POST";
Request.ContentLength = bodyStream.Length;
Request.BeginGetRequestStream(iar =>
{
Stream requestStream = Request.EndGetRequestStream(iar);
bodyStream.Position = 0;
byte[] buff = new byte[buffer_size];
int read = 0;
while ((read = bodyStream.Read(buff, 0, buffer_size)) > 0)
{
requestStream.Write(buff, 0, read);
requestStream.Flush();
Console.WriteLine(read.ToString());
}
requestStream.Close();
beginResponse();
}, null);
}
else
{
//GET
beginResponse();
}
}
private void beginResponse()
{
Request.BeginGetResponse(iar =>
{
try
{
Response = Request.EndGetResponse(iar);
ContentLength = (int)Response.ContentLength;
responseStream = Response.GetResponseStream();
buffer = new byte[buffer_size];
responseStream.BeginRead(buffer, 0, buffer_size, readCallback, null);
}
catch (Exception e)
{
Complete(e);
}
}, null);
}
private void readCallback(IAsyncResult result)
{
try
{
int readBytes = responseStream.EndRead(result);
if (readBytes > 0)
{
BytesRead += readBytes;
ResponseStream.Write(buffer, 0, readBytes);
responseStream.BeginRead(buffer, 0, buffer_size, readCallback, null);
}
else
{
ResponseStream.Seek(0, SeekOrigin.Begin);
Complete();
}
}
catch (Exception e)
{
Complete(e);
}
}
public virtual void BlockingPerform(int timeout = 0)
{
Exception exc = null;
bool completed = false;
Finished += delegate (pWebRequest r, Exception e)
{
completed = true;
exc = e;
};
Perform();
int waitedTime = 0;
while (!completed)
{
Thread.Sleep(20);
waitedTime += 20;
if (timeout > 0 && waitedTime > timeout)
{
Abort();
throw new TimeoutException();
}
}
if (exc != null) throw exc;
}
protected virtual void Complete(Exception e = null)
{
RequestCompleteHandler finished = Finished;
if (finished != null)
finished(this, e);
}
public virtual void Abort()
{
Aborted = true;
if (request != null)
request.Abort();
}
public delegate void RequestUpdateHandler(pWebRequest request, long current, long total);
public delegate void RequestCompleteHandler(pWebRequest request, Exception e);
public delegate void RequestStartedHandler(pWebRequest request);
public void AddHeader(string key, string val)
{
Request.Headers.Add(key, val);
}
public void AddRaw(Stream stream)
{
stream.CopyTo(bodyStream);
}
public void AddRaw(byte[] data)
{
bodyStream.Write(data, 0, data.Length);
}
public void AddFile(string key, byte[] data)
{
Parameters.Add(key, data);
}
public void AddParameter(string key, string val)
{
Parameters.Add(key, val);
}
}
public class pWebRequest<T> : pWebRequest
{
public pWebRequest(string url, params object[] args) : base(url, args)
{
}
public T ResponseObject
{
get
{
return JsonConvert.DeserializeObject<T>(ResponseString);
}
}
}
/// <summary>
/// Downloads a file from the internet to a specified location
/// </summary>
public class pFileWebRequest : pWebRequest
{
public string Filename;
protected override Stream CreateOutputStream()
{
return new FileStream(Filename, FileMode.Create, FileAccess.Write, FileShare.Write, 32768);
}
public pFileWebRequest(string filename, string url) : base(url)
{
Filename = filename;
}
protected override void Complete(Exception e = null)
{
if (ResponseStream != null) ResponseStream.Close();
if (e != null) GeneralHelper.FileDelete(Filename);
base.Complete(e);
}
}
public static class ExtensionMethods
{
public static void WriteLineExplicit(this Stream s)
{
s.WriteLineExplicit(string.Empty);
}
public static void WriteLineExplicit(this Stream s, object obj)
{
s.WriteLineExplicit(obj.ToString());
}
public static void WriteLineExplicit(this Stream s, string str, params object[] param)
{
if (param.Length > 0)
str = string.Format(str, param);
str += "\r\n";
byte[] data = Encoding.ASCII.GetBytes(str);
s.Write(data, 0, data.Length);
}
}
}
Copy link

ghost commented Aug 31, 2015

Hmmm i will look into the problem!

@camas
Copy link

camas commented Aug 31, 2015

Line 128: The second end-line being written adds two bytes to the data when I try using it, which might be the problem. No idea how you parse this server side though so it might just work for you anyway. I was using http://www.posttestserver.com/ to test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment