Skip to content

Instantly share code, notes, and snippets.

@kemalincekara
Last active December 17, 2017 10:31
Show Gist options
  • Save kemalincekara/694b393abb656ee40fd58ec8a45ebdfe to your computer and use it in GitHub Desktop.
Save kemalincekara/694b393abb656ee40fd58ec8a45ebdfe to your computer and use it in GitHub Desktop.
[C#] Get - Post Submitter
//This is by "rakker" from "The Life and Times of a Dev".URL: http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
public class PostSubmitter : IDisposable
{
/// <summary>
/// determines what type of post to perform.
/// </summary>
public enum PostTypeEnum
{
/// <summary>
/// Does a GET against the source.
/// </summary>
Get,
/// <summary>
/// Does a POST against the source.
/// </summary>
Post
}
/// <summary>Occurs when a web exception event is encountered.</summary>
public event WebExceptionEvent WebExceptionEvent;
#region " Const "
/// <summary>
/// Default constructor.
/// </summary>
public PostSubmitter()
{
Querystrings = new NameValueCollection();
PostItems = new NameValueCollection();
Type = PostTypeEnum.Get;
BufferSize = 4096;
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36";
Files = null;
}
/// <summary>
/// Constructor that accepts a url as a parameter
/// </summary>
/// <param name="url">The url where the post will be submitted to.</param>
public PostSubmitter(string url)
: this()
{
Url = url;
}
/// <summary>
/// Constructor allowing the setting of the url and items to post.
/// </summary>
/// <param name="url">the url for the post.</param>
/// <param name="values">The values for the post.</param>
public PostSubmitter(string url, NameValueCollection values)
: this(url)
{
PostItems = values;
}
#endregion
#region " Properties "
/// <summary>
/// Gets or sets the url to submit the post to.
/// </summary>
public string Url { get; set; }
public NameValueCollection Querystrings { get; set; }
/// <summary>
/// Gets or sets the name value collection of items to post.
/// </summary>
public NameValueCollection PostItems { get; set; }
/// <summary>
/// Gets or sets the type of action to perform against the url.
/// </summary>
public PostTypeEnum Type { get; set; }
/// <summary>If set, specifies the cookie container associated with this object.</summary>
/// <value>An instance of the <see cref="CookieContainer"/> class.</value>
public CookieContainer CookieContainer { get; set; }
public int BufferSize { get; set; }
public string UserAgent { get; set; }
public List<UploadFile> Files { get; set; }
#endregion
/// <summary>
/// Posts the supplied data to specified url.
/// </summary>
/// <returns>a string containing the result of the post.</returns>
public string Post() => PostData(Url, StringBuilt(PostItems), StringBuilt(Querystrings));
/// <summary>
/// Posts the supplied data to specified url.
/// </summary>
/// <param name="url">The url to post to.</param>
/// <returns>a string containing the result of the post.</returns>
public string Post(string url)
{
Url = url;
return this.Post();
}
/// <summary>
/// Posts the supplied data to specified url.
/// </summary>
/// <param name="url">The url to post to.</param>
/// <param name="values">The values to post.</param>
/// <returns>a string containing the result of the post.</returns>
public string Post(string url, NameValueCollection values)
{
PostItems = values;
return this.Post(url);
}
/// <summary>
/// Posts data to a specified url. Note that this assumes that you have already url encoded the post data.
/// </summary>
/// <param name="postData">The data to post.</param>
/// <param name="url">the url to post to.</param>
/// <returns>Returns the result of the post.</returns>
private string PostData(string url, string postData, string queryString, int retries = 1)
{
UriBuilder uri = new UriBuilder(url);
if (uri.Query.Length == 0)
uri.Query = queryString;
//Uri uri = new Uri(url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri.Uri);
request.UserAgent = UserAgent;
request.KeepAlive = true;
request.CookieContainer = CookieContainer;
if (Files != null && Files.Count > 0)
{
var boundary = $"---------------------------{DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo)}";
request.Method = "POST";
request.ContentType = $"multipart/form-data; boundary={boundary}";
//request.Headers.Add("Cache-Control", "no-cache");
request.Headers.Add(HttpRequestHeader.CacheControl, "no-cache");
boundary = "--" + boundary;
using (var requestStream = request.GetRequestStream())
{
try
{
// Write the values
if (PostItems != null)
foreach (string name in PostItems.Keys)
{
var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{1}", name, Environment.NewLine));
requestStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.UTF8.GetBytes(PostItems[name] + Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
}
// Write the files
foreach (var file in Files)
{
if (string.IsNullOrEmpty(file.FileAddress) && file.Stream == null) continue;
var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.UTF8.GetBytes(string.Format("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"{2}", file.Name, file.Filename, Environment.NewLine));
requestStream.Write(buffer, 0, buffer.Length);
buffer = Encoding.ASCII.GetBytes(string.Format("Content-Type: {0}{1}{1}", file.ContentType, Environment.NewLine));
requestStream.Write(buffer, 0, buffer.Length);
//file.Stream.CopyTo(requestStream);
if (!string.IsNullOrEmpty(file.FileAddress))
{
using (FileStream readIn = new FileStream(file.FileAddress, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
readIn.Seek(0, SeekOrigin.Begin); // move to the start of the file
byte[] fileData = new byte[checked((uint)Math.Min(BufferSize, (int)readIn.Length))];
int bytes;
while ((bytes = readIn.Read(fileData, 0, fileData.Length)) > 0)
requestStream.Write(fileData, 0, bytes);
}
}
else if (file.Stream != null)
{
file.Stream.Seek(0, SeekOrigin.Begin); // move to the start of the file
byte[] fileData = new byte[checked((uint)Math.Min(BufferSize, (int)file.Stream.Length))];
int bytes;
while ((bytes = file.Stream.Read(fileData, 0, fileData.Length)) > 0)
requestStream.Write(fileData, 0, bytes);
file.Stream.Close();
file.Stream.Dispose();
}
buffer = Encoding.ASCII.GetBytes(Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
}
var boundaryBuffer = Encoding.ASCII.GetBytes(boundary + "--");
requestStream.Write(boundaryBuffer, 0, boundaryBuffer.Length);
}
catch (WebException e)
{
WebExceptionEvent?.Invoke(this, new WebExceptionEventArgs(e, url, postData, Type));
return "";
}
catch (Exception)
{
return "";
}
}
}
else if (Type == PostTypeEnum.Post)
{
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
try
{
using (Stream writeStream = request.GetRequestStream())
{
byte[] bytes = new UTF8Encoding(false).GetBytes(postData);
writeStream.Write(bytes, 0, bytes.Length);
}
}
catch (WebException e)
{
WebExceptionEvent?.Invoke(this, new WebExceptionEventArgs(e, url, postData, Type));
return "";
}
catch (Exception)
{
return "";
}
}
else
request.Method = "GET";
string result = null;
//Thanks to supersnail11 for this block here (http://www.facepunch.com/threads/1144771?p=33818537&viewfull=1#post33818537)
while (result == null && retries-- > 0)
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8))
result = readStream.ReadToEnd();
}
catch (WebException e)
{
WebExceptionEvent?.Invoke(this, new WebExceptionEventArgs(e, url, postData, Type));
}
return result;
}
/// <summary>
/// Encodes an item and adds an item to the string.
/// </summary>
/// <param name="baseRequest">The previously encoded data.</param>
/// <param name="dataItem">The data to encode.</param>
/// <returns>A string containing the old data and the previously encoded data.</returns>
private void EncodeAndAddItem(ref StringBuilder baseRequest, string key, string dataItem)
{
if (baseRequest == null)
baseRequest = new StringBuilder();
if (baseRequest.Length != 0)
baseRequest.Append("&");
baseRequest.Append(key);
baseRequest.Append("=");
baseRequest.Append(Uri.EscapeDataString(dataItem));
}
private string StringBuilt(NameValueCollection collection)
{
var builder = new StringBuilder();
for (int i = 0; i < collection.Count; i++)
EncodeAndAddItem(ref builder, collection.GetKey(i), collection[i]);
return builder.ToString();
}
#region " Dispose "
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (Files != null)
{
Files.Clear();
Files = null;
}
Querystrings.Clear();
Querystrings = null;
PostItems.Clear();
PostItems = null;
CookieContainer = null;
}
}
disposed = true;
}
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
~PostSubmitter()
{
Dispose(false);
}
#endregion
}
public class WebExceptionEventArgs : EventArgs
{
public PostSubmitter.PostTypeEnum Method { get; protected set; }
public WebException Exception { get; protected set; }
public string PostData { get; protected set; }
public string Url { get; protected set; }
public WebExceptionEventArgs(WebException e, string url, string postData, PostSubmitter.PostTypeEnum method)
{
Exception = e;
Url = url;
PostData = postData;
Method = method;
}
}
public delegate void WebExceptionEvent(object sender, WebExceptionEventArgs e);
public class UploadFile
{
public UploadFile()
{
ContentType = "application/octet-stream";
}
public string Name { get; set; }
public string Filename { get; set; }
public string ContentType { get; set; }
public Stream Stream { get; set; }
public string FileAddress { get; set; }
}
using System;
using System.Collections.Generic;
namespace GetPostSubmitter
{
public static class Program
{
public static void Main(string[] args)
{
using (PostSubmitter post = new PostSubmitter()
{
Url = "https://requestb.in/1bpo0hl1"
})
{
post.Querystrings.Add("id", "67");
post.Querystrings.Add("islem", "guncelle");
post.PostItems.Add("csharp", "developer");
post.PostItems.Add("bool", bool.TrueString);
post.Type = PostSubmitter.PostTypeEnum.Post;
post.WebExceptionEvent += Post_WebExceptionEvent;
Console.WriteLine(post.Post());
// Dosya Upload
post.Files = new List<UploadFile>()
{
new UploadFile()
{
Filename = "test.txt",
Name = "txtupload",
FileAddress = @"C:\Windows\win.ini",
ContentType = "text/plain"
}
};
Console.WriteLine(post.Post());
}
Console.ReadKey();
}
private static void Post_WebExceptionEvent(object sender, WebExceptionEventArgs e)
{
Console.WriteLine("Url: {0}", e.Url);
Console.WriteLine("Method: {0}", e.Method);
Console.WriteLine("PostData: {0}", e.PostData);
Console.WriteLine("Exception: {0}", e.Exception);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment