mirror of
https://github.com/greenshot/greenshot
synced 2025-07-14 17:13:44 -07:00
Untested performance improvements with uploads, in short the image is directly stored to the upload stream instead of writing a stream to a byte[]. Expecting a small performance improvement, and a lot less memory usage while uploading.
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2125 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
c983567827
commit
abe79e65e9
6 changed files with 230 additions and 182 deletions
|
@ -138,42 +138,39 @@ namespace GreenshotImgurPlugin {
|
||||||
/// <returns>true if the upload succeeded</returns>
|
/// <returns>true if the upload succeeded</returns>
|
||||||
public bool Upload(ICaptureDetails captureDetails, Image image, out string uploadURL) {
|
public bool Upload(ICaptureDetails captureDetails, Image image, out string uploadURL) {
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
||||||
using (MemoryStream stream = new MemoryStream()) {
|
try {
|
||||||
ImageOutput.SaveToStream(image, stream, outputSettings);
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
||||||
try {
|
ImgurInfo imgurInfo = null;
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
|
||||||
ImgurInfo imgurInfo = null;
|
|
||||||
|
|
||||||
// Run upload in the background
|
// Run upload in the background
|
||||||
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("imgur", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("imgur", LangKey.communication_wait),
|
||||||
delegate() {
|
delegate() {
|
||||||
imgurInfo = ImgurUtils.UploadToImgur(stream.GetBuffer(), (int)stream.Length, captureDetails.Title, filename);
|
imgurInfo = ImgurUtils.UploadToImgur(image, outputSettings, captureDetails.Title, filename);
|
||||||
LOG.InfoFormat("Storing imgur upload for hash {0} and delete hash {1}", imgurInfo.Hash, imgurInfo.DeleteHash);
|
LOG.InfoFormat("Storing imgur upload for hash {0} and delete hash {1}", imgurInfo.Hash, imgurInfo.DeleteHash);
|
||||||
config.ImgurUploadHistory.Add(imgurInfo.Hash, imgurInfo.DeleteHash);
|
config.ImgurUploadHistory.Add(imgurInfo.Hash, imgurInfo.DeleteHash);
|
||||||
config.runtimeImgurHistory.Add(imgurInfo.Hash, imgurInfo);
|
config.runtimeImgurHistory.Add(imgurInfo.Hash, imgurInfo);
|
||||||
CheckHistory();
|
CheckHistory();
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
imgurInfo.Image = ImageHelper.CreateThumbnail(image, 90, 90);
|
|
||||||
IniConfig.Save();
|
|
||||||
uploadURL = null;
|
|
||||||
try {
|
|
||||||
if (config.UsePageLink) {
|
|
||||||
uploadURL = imgurInfo.Page;
|
|
||||||
Clipboard.SetText(imgurInfo.Page);
|
|
||||||
} else {
|
|
||||||
uploadURL = imgurInfo.Original;
|
|
||||||
Clipboard.SetText(imgurInfo.Original);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
LOG.Error("Can't write to clipboard: ", ex);
|
|
||||||
}
|
}
|
||||||
return true;
|
);
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.Error(e);
|
imgurInfo.Image = ImageHelper.CreateThumbnail(image, 90, 90);
|
||||||
MessageBox.Show(Language.GetString("imgur", LangKey.upload_failure) + " " + e.Message);
|
IniConfig.Save();
|
||||||
|
uploadURL = null;
|
||||||
|
try {
|
||||||
|
if (config.UsePageLink) {
|
||||||
|
uploadURL = imgurInfo.Page;
|
||||||
|
Clipboard.SetText(imgurInfo.Page);
|
||||||
|
} else {
|
||||||
|
uploadURL = imgurInfo.Original;
|
||||||
|
Clipboard.SetText(imgurInfo.Original);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOG.Error("Can't write to clipboard: ", ex);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.Error(e);
|
||||||
|
MessageBox.Show(Language.GetString("imgur", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
uploadURL = null;
|
uploadURL = null;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System.Web;
|
||||||
|
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
|
using Greenshot.Plugin;
|
||||||
|
|
||||||
namespace GreenshotImgurPlugin {
|
namespace GreenshotImgurPlugin {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -97,9 +98,12 @@ namespace GreenshotImgurPlugin {
|
||||||
/// Do the actual upload to Imgur
|
/// Do the actual upload to Imgur
|
||||||
/// For more details on the available parameters, see: http://api.imgur.com/resources_anon
|
/// For more details on the available parameters, see: http://api.imgur.com/resources_anon
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imageData">byte[] with image data</param>
|
/// <param name="image">Image to upload</param>
|
||||||
/// <returns>ImgurResponse</returns>
|
/// <param name="outputSettings">OutputSettings for the image file format</param>
|
||||||
public static ImgurInfo UploadToImgur(byte[] imageData, int dataLength, string title, string filename) {
|
/// <param name="title">Title</param>
|
||||||
|
/// <param name="filename">Filename</param>
|
||||||
|
/// <returns>ImgurInfo with details</returns>
|
||||||
|
public static ImgurInfo UploadToImgur(Image image, OutputSettings outputSettings, string title, string filename) {
|
||||||
IDictionary<string, object> uploadParameters = new Dictionary<string, object>();
|
IDictionary<string, object> uploadParameters = new Dictionary<string, object>();
|
||||||
|
|
||||||
string responseString = null;
|
string responseString = null;
|
||||||
|
@ -118,19 +122,18 @@ namespace GreenshotImgurPlugin {
|
||||||
HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(config.ImgurApiUrl + "/upload.xml?" + NetworkHelper.GenerateQueryParameters(uploadParameters));
|
HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(config.ImgurApiUrl + "/upload.xml?" + NetworkHelper.GenerateQueryParameters(uploadParameters));
|
||||||
|
|
||||||
webRequest.Method = "POST";
|
webRequest.Method = "POST";
|
||||||
webRequest.ContentType = "image/png";
|
webRequest.ContentType = "image/" + outputSettings.Format.ToString();
|
||||||
webRequest.ServicePoint.Expect100Continue = false;
|
webRequest.ServicePoint.Expect100Continue = false;
|
||||||
using (var requestStream = webRequest.GetRequestStream()) {
|
using (var requestStream = webRequest.GetRequestStream()) {
|
||||||
requestStream.Write(imageData, 0, dataLength);
|
ImageOutput.SaveToStream(image, requestStream, outputSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (WebResponse response = webRequest.GetResponse()) {
|
using (WebResponse response = webRequest.GetResponse()) {
|
||||||
LogCredits(response);
|
LogCredits(response);
|
||||||
Stream responseStream = response.GetResponseStream();
|
using (StreamReader reader = new StreamReader(response.GetResponseStream(), true)) {
|
||||||
StreamReader responseReader = new StreamReader(responseStream);
|
responseString = reader.ReadToEnd();
|
||||||
responseString = responseReader.ReadToEnd();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
OAuthSession oAuth = new OAuthSession(ImgurCredentials.CONSUMER_KEY, ImgurCredentials.CONSUMER_SECRET);
|
OAuthSession oAuth = new OAuthSession(ImgurCredentials.CONSUMER_KEY, ImgurCredentials.CONSUMER_SECRET);
|
||||||
oAuth.BrowserSize = new Size(650, 500);
|
oAuth.BrowserSize = new Size(650, 500);
|
||||||
|
@ -165,7 +168,7 @@ namespace GreenshotImgurPlugin {
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
uploadParameters.Add("name", filename);
|
uploadParameters.Add("name", filename);
|
||||||
}
|
}
|
||||||
uploadParameters.Add("image", new FileParameter(imageData, filename, "image/png", dataLength));
|
uploadParameters.Add("image", new ImageParameter(image, outputSettings, filename));
|
||||||
responseString = oAuth.MakeRequest(HTTPMethod.POST, apiUrl, uploadParameters, null, null);
|
responseString = oAuth.MakeRequest(HTTPMethod.POST, apiUrl, uploadParameters, null, null);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.Error("Upload to imgur gave an exeption: ", ex);
|
LOG.Error("Upload to imgur gave an exeption: ", ex);
|
||||||
|
@ -211,9 +214,9 @@ namespace GreenshotImgurPlugin {
|
||||||
try {
|
try {
|
||||||
using (WebResponse response = webRequest.GetResponse()) {
|
using (WebResponse response = webRequest.GetResponse()) {
|
||||||
LogCredits(response);
|
LogCredits(response);
|
||||||
Stream responseStream = response.GetResponseStream();
|
using (StreamReader reader = new StreamReader(response.GetResponseStream(), true)) {
|
||||||
StreamReader responseReader = new StreamReader(responseStream);
|
responseString = reader.ReadToEnd();
|
||||||
responseString = responseReader.ReadToEnd();
|
}
|
||||||
}
|
}
|
||||||
} catch (WebException wE) {
|
} catch (WebException wE) {
|
||||||
if (wE.Status == WebExceptionStatus.ProtocolError) {
|
if (wE.Status == WebExceptionStatus.ProtocolError) {
|
||||||
|
@ -243,9 +246,9 @@ namespace GreenshotImgurPlugin {
|
||||||
string responseString;
|
string responseString;
|
||||||
using (WebResponse response = webRequest.GetResponse()) {
|
using (WebResponse response = webRequest.GetResponse()) {
|
||||||
LogCredits(response);
|
LogCredits(response);
|
||||||
Stream responseStream = response.GetResponseStream();
|
using (StreamReader reader = new StreamReader(response.GetResponseStream(), true)) {
|
||||||
StreamReader responseReader = new StreamReader(responseStream);
|
responseString = reader.ReadToEnd();
|
||||||
responseString = responseReader.ReadToEnd();
|
}
|
||||||
}
|
}
|
||||||
LOG.InfoFormat("Delete result: {0}", responseString);
|
LOG.InfoFormat("Delete result: {0}", responseString);
|
||||||
} catch (WebException wE) {
|
} catch (WebException wE) {
|
||||||
|
|
|
@ -110,37 +110,34 @@ namespace GreenshotPhotobucketPlugin {
|
||||||
/// <returns>true if the upload succeeded</returns>
|
/// <returns>true if the upload succeeded</returns>
|
||||||
public bool Upload(ICaptureDetails captureDetails, Image image, out string uploadURL) {
|
public bool Upload(ICaptureDetails captureDetails, Image image, out string uploadURL) {
|
||||||
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors);
|
||||||
using (MemoryStream stream = new MemoryStream()) {
|
try {
|
||||||
ImageOutput.SaveToStream(image, stream, outputSettings);
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
||||||
try {
|
PhotobucketInfo photobucketInfo = null;
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(config.UploadFormat, captureDetails));
|
|
||||||
PhotobucketInfo photobucketInfo = null;
|
|
||||||
|
|
||||||
// Run upload in the background
|
// Run upload in the background
|
||||||
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("photobucket", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("photobucket", LangKey.communication_wait),
|
||||||
delegate() {
|
delegate() {
|
||||||
photobucketInfo = PhotobucketUtils.UploadToPhotobucket(stream.GetBuffer(), (int)stream.Length, captureDetails.Title, filename);
|
photobucketInfo = PhotobucketUtils.UploadToPhotobucket(image, outputSettings, captureDetails.Title, filename);
|
||||||
}
|
|
||||||
);
|
|
||||||
// This causes an exeption if the upload failed :)
|
|
||||||
LOG.DebugFormat("Uploaded to Photobucket page: " + photobucketInfo.Page);
|
|
||||||
uploadURL = null;
|
|
||||||
try {
|
|
||||||
if (config.UsePageLink) {
|
|
||||||
uploadURL = photobucketInfo.Page;
|
|
||||||
Clipboard.SetText(photobucketInfo.Page);
|
|
||||||
} else {
|
|
||||||
uploadURL = photobucketInfo.Original;
|
|
||||||
Clipboard.SetText(photobucketInfo.Original);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
LOG.Error("Can't write to clipboard: ", ex);
|
|
||||||
}
|
}
|
||||||
return true;
|
);
|
||||||
} catch (Exception e) {
|
// This causes an exeption if the upload failed :)
|
||||||
LOG.Error(e);
|
LOG.DebugFormat("Uploaded to Photobucket page: " + photobucketInfo.Page);
|
||||||
MessageBox.Show(Language.GetString("photobucket", LangKey.upload_failure) + " " + e.Message);
|
uploadURL = null;
|
||||||
|
try {
|
||||||
|
if (config.UsePageLink) {
|
||||||
|
uploadURL = photobucketInfo.Page;
|
||||||
|
Clipboard.SetText(photobucketInfo.Page);
|
||||||
|
} else {
|
||||||
|
uploadURL = photobucketInfo.Original;
|
||||||
|
Clipboard.SetText(photobucketInfo.Original);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOG.Error("Can't write to clipboard: ", ex);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.Error(e);
|
||||||
|
MessageBox.Show(Language.GetString("photobucket", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
uploadURL = null;
|
uploadURL = null;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System.Web;
|
||||||
|
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using Greenshot.IniFile;
|
using Greenshot.IniFile;
|
||||||
|
using Greenshot.Plugin;
|
||||||
|
|
||||||
namespace GreenshotPhotobucketPlugin {
|
namespace GreenshotPhotobucketPlugin {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -47,7 +48,7 @@ namespace GreenshotPhotobucketPlugin {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imageData">byte[] with image data</param>
|
/// <param name="imageData">byte[] with image data</param>
|
||||||
/// <returns>PhotobucketResponse</returns>
|
/// <returns>PhotobucketResponse</returns>
|
||||||
public static PhotobucketInfo UploadToPhotobucket(byte[] imageData, int dataLength, string title, string filename) {
|
public static PhotobucketInfo UploadToPhotobucket(Image image, OutputSettings outputSettings, string title, string filename) {
|
||||||
string responseString;
|
string responseString;
|
||||||
|
|
||||||
OAuthSession oAuth = new OAuthSession("149833145", "ebd828180b11103c010c7e71c66f6bcb");
|
OAuthSession oAuth = new OAuthSession("149833145", "ebd828180b11103c010c7e71c66f6bcb");
|
||||||
|
@ -77,7 +78,7 @@ namespace GreenshotPhotobucketPlugin {
|
||||||
oAuth.Token = config.Token;
|
oAuth.Token = config.Token;
|
||||||
oAuth.TokenSecret = config.TokenSecret;
|
oAuth.TokenSecret = config.TokenSecret;
|
||||||
|
|
||||||
Dictionary<string ,string> parameters = new Dictionary<string, string>();
|
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||||
// add album
|
// add album
|
||||||
parameters.Add("id", "Apex75/greenshot");
|
parameters.Add("id", "Apex75/greenshot");
|
||||||
// add type
|
// add type
|
||||||
|
@ -95,7 +96,7 @@ namespace GreenshotPhotobucketPlugin {
|
||||||
oAuth.Sign(HTTPMethod.POST, apiUrl, parameters);
|
oAuth.Sign(HTTPMethod.POST, apiUrl, parameters);
|
||||||
apiUrl = apiUrl.Replace("api.photobucket.com", config.SubDomain);
|
apiUrl = apiUrl.Replace("api.photobucket.com", config.SubDomain);
|
||||||
// Add image
|
// Add image
|
||||||
parameters.Add("uploadfile", new FileParameter(imageData, filename, "image/png", dataLength));
|
parameters.Add("uploadfile", new ImageParameter(image, outputSettings, filename));
|
||||||
responseString = oAuth.MakeRequest(HTTPMethod.POST, apiUrl, parameters, null, null);
|
responseString = oAuth.MakeRequest(HTTPMethod.POST, apiUrl, parameters, null, null);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOG.Error("Error uploading to Photobucket.", ex);
|
LOG.Error("Error uploading to Photobucket.", ex);
|
||||||
|
|
|
@ -30,6 +30,7 @@ using Greenshot.IniFile;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Net.Security;
|
using System.Net.Security;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using Greenshot.Plugin;
|
||||||
|
|
||||||
namespace GreenshotPlugin.Core {
|
namespace GreenshotPlugin.Core {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -58,8 +59,9 @@ namespace GreenshotPlugin.Core {
|
||||||
HttpWebRequest request = (HttpWebRequest)CreateWebRequest(url);
|
HttpWebRequest request = (HttpWebRequest)CreateWebRequest(url);
|
||||||
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
||||||
if (request.HaveResponse) {
|
if (request.HaveResponse) {
|
||||||
StreamReader reader = new StreamReader(response.GetResponseStream(), encoding);
|
using (StreamReader reader = new StreamReader(response.GetResponseStream(), encoding)) {
|
||||||
return reader.ReadToEnd();
|
return reader.ReadToEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -241,5 +243,139 @@ namespace GreenshotPlugin.Core {
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write Multipart Form Data directly to the HttpWebRequest response stream
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="webRequest">HttpWebRequest to write the multipart form data to</param>
|
||||||
|
/// <param name="postParameters">Parameters to include in the multipart form data</param>
|
||||||
|
public static void WriteMultipartFormData(HttpWebRequest webRequest, IDictionary<string, object> postParameters) {
|
||||||
|
string boundary = String.Format("----------{0:N}", Guid.NewGuid());
|
||||||
|
webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
|
||||||
|
|
||||||
|
bool needsCLRF = false;
|
||||||
|
using (Stream formDataStream = webRequest.GetRequestStream()) {
|
||||||
|
foreach (var param in postParameters) {
|
||||||
|
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
|
||||||
|
// Skip it on the first parameter, add it to subsequent parameters.
|
||||||
|
if (needsCLRF) {
|
||||||
|
formDataStream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, Encoding.UTF8.GetByteCount("\r\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
needsCLRF = true;
|
||||||
|
|
||||||
|
if (param.Value is IBinaryParameter) {
|
||||||
|
IBinaryParameter binaryParameter = (IBinaryParameter)param.Value;
|
||||||
|
binaryParameter.WriteFormDataToStream(boundary, param.Key, formDataStream);
|
||||||
|
} else {
|
||||||
|
string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
|
||||||
|
boundary,
|
||||||
|
param.Key,
|
||||||
|
param.Value);
|
||||||
|
formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, Encoding.UTF8.GetByteCount(postData));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the end of the request. Start with a newline
|
||||||
|
string footer = "\r\n--" + boundary + "--\r\n";
|
||||||
|
formDataStream.Write(Encoding.UTF8.GetBytes(footer), 0, Encoding.UTF8.GetByteCount(footer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IBinaryParameter {
|
||||||
|
void WriteFormDataToStream(string boundary, string key, Stream formDataStream);
|
||||||
|
void WriteToStream(Stream formDataStream);
|
||||||
|
string ToBase64String();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A container to supply files to a Multi-part form data upload
|
||||||
|
/// </summary>
|
||||||
|
public class FileParameter : IBinaryParameter {
|
||||||
|
private byte[] file;
|
||||||
|
private string fileName;
|
||||||
|
private string contentType;
|
||||||
|
private int fileSize;
|
||||||
|
public FileParameter(byte[] file) : this(file, null) {
|
||||||
|
}
|
||||||
|
public FileParameter(byte[] file, string filename) : this(file, filename, null) {
|
||||||
|
}
|
||||||
|
public FileParameter(byte[] file, string filename, string contenttype) : this(file, filename, contenttype, 0) {
|
||||||
|
}
|
||||||
|
public FileParameter(byte[] file, string filename, string contenttype, int filesize) {
|
||||||
|
this.file = file;
|
||||||
|
this.fileName = filename;
|
||||||
|
this.contentType = contenttype;
|
||||||
|
if (filesize == 0) {
|
||||||
|
this.fileSize = file.Length;
|
||||||
|
} else {
|
||||||
|
this.fileSize = filesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToBase64String() {
|
||||||
|
return System.Convert.ToBase64String(file, 0, fileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteFormDataToStream(string boundary, string key, Stream formDataStream) {
|
||||||
|
// Add just the first part of this param, since we will write the file data directly to the Stream
|
||||||
|
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
|
||||||
|
boundary,
|
||||||
|
key,
|
||||||
|
fileName ?? key,
|
||||||
|
contentType ?? "application/octet-stream");
|
||||||
|
|
||||||
|
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
||||||
|
|
||||||
|
// Write the file data directly to the Stream, rather than serializing it to a string.
|
||||||
|
formDataStream.Write(file, 0, fileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteToStream(Stream dataStream) {
|
||||||
|
// Write the file data directly to the Stream, rather than serializing it to a string.
|
||||||
|
dataStream.Write(file, 0, fileSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A container to supply images to a Multi-part form data upload
|
||||||
|
/// </summary>
|
||||||
|
public class ImageParameter : IBinaryParameter {
|
||||||
|
private Image image;
|
||||||
|
private OutputSettings outputSettings;
|
||||||
|
private string fileName;
|
||||||
|
|
||||||
|
public ImageParameter(Image image, OutputSettings outputSettings, string filename) {
|
||||||
|
this.image = image;
|
||||||
|
this.outputSettings = outputSettings;
|
||||||
|
this.fileName = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToBase64String() {
|
||||||
|
using (MemoryStream stream = new MemoryStream()) {
|
||||||
|
ImageOutput.SaveToStream(image, stream, outputSettings);
|
||||||
|
return System.Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteFormDataToStream(string boundary, string key, Stream formDataStream) {
|
||||||
|
// Add just the first part of this param, since we will write the file data directly to the Stream
|
||||||
|
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
|
||||||
|
boundary,
|
||||||
|
key,
|
||||||
|
fileName ?? key,
|
||||||
|
"image/" + outputSettings.Format.ToString());
|
||||||
|
|
||||||
|
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
||||||
|
|
||||||
|
// Write the file data directly to the Stream, rather than serializing it to a string.
|
||||||
|
ImageOutput.SaveToStream(image, formDataStream, outputSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteToStream(Stream dataStream) {
|
||||||
|
// Write the file data directly to the Stream, rather than serializing it to a string.
|
||||||
|
ImageOutput.SaveToStream(image, dataStream, outputSettings);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using Greenshot.Plugin;
|
||||||
|
|
||||||
namespace GreenshotPlugin.Core {
|
namespace GreenshotPlugin.Core {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -41,22 +42,6 @@ namespace GreenshotPlugin.Core {
|
||||||
|
|
||||||
public enum HTTPMethod { GET, POST, PUT, DELETE };
|
public enum HTTPMethod { GET, POST, PUT, DELETE };
|
||||||
|
|
||||||
public class FileParameter {
|
|
||||||
public byte[] File { get; set; }
|
|
||||||
public string FileName { get; set; }
|
|
||||||
public string ContentType { get; set; }
|
|
||||||
public int FileSize {get; set; }
|
|
||||||
public FileParameter(byte[] file) : this(file, null) { }
|
|
||||||
public FileParameter(byte[] file, string filename) : this(file, filename, null) { }
|
|
||||||
public FileParameter(byte[] file, string filename, string contenttype) : this(file, filename, contenttype, 0) { }
|
|
||||||
public FileParameter(byte[] file, string filename, string contenttype, int filesize) {
|
|
||||||
File = file;
|
|
||||||
FileName = filename;
|
|
||||||
ContentType = contenttype;
|
|
||||||
FileSize = filesize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OAuthSession {
|
public class OAuthSession {
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OAuthSession));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OAuthSession));
|
||||||
protected const string OAUTH_VERSION = "1.0";
|
protected const string OAUTH_VERSION = "1.0";
|
||||||
|
@ -393,7 +378,7 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <param name="contentType">contenttype for the postdata</param>
|
/// <param name="contentType">contenttype for the postdata</param>
|
||||||
/// <param name="postData">Data to post (MemoryStream)</param>
|
/// <param name="postData">Data to post (MemoryStream)</param>
|
||||||
/// <returns>The web server response.</returns>
|
/// <returns>The web server response.</returns>
|
||||||
public string MakeOAuthRequest(HTTPMethod method, string requestURL, IDictionary<string, object> parameters, string contentType, MemoryStream postData) {
|
public string MakeOAuthRequest(HTTPMethod method, string requestURL, IDictionary<string, object> parameters, string contentType, IBinaryParameter postData) {
|
||||||
if (parameters == null) {
|
if (parameters == null) {
|
||||||
parameters = new Dictionary<string, object>();
|
parameters = new Dictionary<string, object>();
|
||||||
}
|
}
|
||||||
|
@ -495,9 +480,9 @@ namespace GreenshotPlugin.Core {
|
||||||
/// <param name="requestURL"></param>
|
/// <param name="requestURL"></param>
|
||||||
/// <param name="parameters"></param>
|
/// <param name="parameters"></param>
|
||||||
/// <param name="contentType"></param>
|
/// <param name="contentType"></param>
|
||||||
/// <param name="postData"></param>
|
/// <param name="postData">IBinaryParameter</param>
|
||||||
/// <returns>Response from server</returns>
|
/// <returns>Response from server</returns>
|
||||||
public string MakeRequest(HTTPMethod method, string requestURL, IDictionary<string, object> parameters, string contentType, MemoryStream postData) {
|
public string MakeRequest(HTTPMethod method, string requestURL, IDictionary<string, object> parameters, string contentType, IBinaryParameter postData) {
|
||||||
if (parameters == null) {
|
if (parameters == null) {
|
||||||
throw new ArgumentNullException("parameters");
|
throw new ArgumentNullException("parameters");
|
||||||
}
|
}
|
||||||
|
@ -539,19 +524,14 @@ namespace GreenshotPlugin.Core {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HTTPMethod.POST == method && postData == null && requestParameters != null && requestParameters.Count > 0) {
|
if (HTTPMethod.POST == method && postData == null && requestParameters != null && requestParameters.Count > 0) {
|
||||||
|
|
||||||
if (UseMultipartFormData) {
|
if (UseMultipartFormData) {
|
||||||
byte [] data = GetMultipartFormData(requestParameters, out contentType);
|
NetworkHelper.WriteMultipartFormData(webRequest, requestParameters);
|
||||||
webRequest.ContentType = contentType;
|
|
||||||
using (var requestStream = webRequest.GetRequestStream()) {
|
|
||||||
requestStream.Write(data, 0, data.Length);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
StringBuilder form = new StringBuilder();
|
StringBuilder form = new StringBuilder();
|
||||||
foreach (string parameterKey in requestParameters.Keys) {
|
foreach (string parameterKey in requestParameters.Keys) {
|
||||||
if (parameters[parameterKey] is FileParameter) {
|
if (parameters[parameterKey] is IBinaryParameter) {
|
||||||
FileParameter fileParameter = parameters[parameterKey] as FileParameter;
|
IBinaryParameter binaryParameter = parameters[parameterKey] as IBinaryParameter;
|
||||||
form.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0}={1}&", UrlEncode3986(parameterKey), UrlEncode3986(System.Convert.ToBase64String(fileParameter.File, 0, fileParameter.FileSize != 0 ? fileParameter.FileSize : fileParameter.File.Length)));
|
form.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0}={1}&", UrlEncode3986(parameterKey), UrlEncode3986(binaryParameter.ToBase64String()));
|
||||||
} else {
|
} else {
|
||||||
form.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0}={1}&", UrlEncode3986(parameterKey), UrlEncode3986(string.Format("{0}",parameters[parameterKey])));
|
form.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0}={1}&", UrlEncode3986(parameterKey), UrlEncode3986(string.Format("{0}",parameters[parameterKey])));
|
||||||
}
|
}
|
||||||
|
@ -570,7 +550,7 @@ namespace GreenshotPlugin.Core {
|
||||||
webRequest.ContentType = contentType;
|
webRequest.ContentType = contentType;
|
||||||
if (postData != null) {
|
if (postData != null) {
|
||||||
using (var requestStream = webRequest.GetRequestStream()) {
|
using (var requestStream = webRequest.GetRequestStream()) {
|
||||||
requestStream.Write(postData.GetBuffer(), 0, (int)postData.Length);
|
postData.WriteToStream(requestStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -583,85 +563,19 @@ namespace GreenshotPlugin.Core {
|
||||||
return responseData;
|
return responseData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a Multipart Form Data as byte[]
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="postParameters">Parameters to include in the multipart form data</param>
|
|
||||||
/// <param name="contentType">out parameter for contenttype</param>
|
|
||||||
/// <returns>byte[] with Multipart Form Data which can be used to upload</returns>
|
|
||||||
private static byte[] GetMultipartFormData(IDictionary<string, object> postParameters, out string contentType) {
|
|
||||||
string boundary = String.Format("----------{0:N}", Guid.NewGuid());
|
|
||||||
contentType = "multipart/form-data; boundary=" + boundary;
|
|
||||||
Stream formDataStream = new MemoryStream();
|
|
||||||
bool needsCLRF = false;
|
|
||||||
|
|
||||||
foreach (var param in postParameters) {
|
|
||||||
// Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
|
|
||||||
// Skip it on the first parameter, add it to subsequent parameters.
|
|
||||||
if (needsCLRF) {
|
|
||||||
formDataStream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, Encoding.UTF8.GetByteCount("\r\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
needsCLRF = true;
|
|
||||||
|
|
||||||
if (param.Value is FileParameter) {
|
|
||||||
FileParameter fileToUpload = (FileParameter)param.Value;
|
|
||||||
|
|
||||||
// Add just the first part of this param, since we will write the file data directly to the Stream
|
|
||||||
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
|
|
||||||
boundary,
|
|
||||||
param.Key,
|
|
||||||
fileToUpload.FileName ?? param.Key,
|
|
||||||
fileToUpload.ContentType ?? "application/octet-stream");
|
|
||||||
|
|
||||||
formDataStream.Write(Encoding.UTF8.GetBytes(header), 0, Encoding.UTF8.GetByteCount(header));
|
|
||||||
|
|
||||||
// Write the file data directly to the Stream, rather than serializing it to a string.
|
|
||||||
if (fileToUpload.FileSize > 0) {
|
|
||||||
formDataStream.Write(fileToUpload.File, 0, fileToUpload.FileSize);
|
|
||||||
} else {
|
|
||||||
formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
|
|
||||||
boundary,
|
|
||||||
param.Key,
|
|
||||||
param.Value);
|
|
||||||
formDataStream.Write(Encoding.UTF8.GetBytes(postData), 0, Encoding.UTF8.GetByteCount(postData));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the end of the request. Start with a newline
|
|
||||||
string footer = "\r\n--" + boundary + "--\r\n";
|
|
||||||
formDataStream.Write(Encoding.UTF8.GetBytes(footer), 0, Encoding.UTF8.GetByteCount(footer));
|
|
||||||
|
|
||||||
// Dump the Stream into a byte[]
|
|
||||||
formDataStream.Position = 0;
|
|
||||||
byte[] formData = new byte[formDataStream.Length];
|
|
||||||
formDataStream.Read(formData, 0, formData.Length);
|
|
||||||
formDataStream.Close();
|
|
||||||
|
|
||||||
return formData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Process the web response.
|
/// Process the web response.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="webRequest">The request object.</param>
|
/// <param name="webRequest">The request object.</param>
|
||||||
/// <returns>The response data.</returns>
|
/// <returns>The response data.</returns>
|
||||||
protected string WebResponseGet(HttpWebRequest webRequest) {
|
protected string WebResponseGet(HttpWebRequest webRequest) {
|
||||||
StreamReader responseReader = null;
|
string responseData;
|
||||||
string responseData = "";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
|
using (StreamReader reader = new StreamReader(webRequest.GetResponse().GetResponseStream(), true)) {
|
||||||
responseData = responseReader.ReadToEnd();
|
responseData = reader.ReadToEnd();
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
|
||||||
webRequest.GetResponse().GetResponseStream().Close();
|
|
||||||
responseReader.Close();
|
|
||||||
responseReader = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return responseData;
|
return responseData;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue