Created
August 31, 2015 13:20
-
-
Save peppy/cb502fa48631de0331e0 to your computer and use it in GitHub Desktop.
Broken code (AddFile fails with byte[] around 50k or more)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.