I need to do a HTTP POST using C#. It needs to do a postback the same way as an IE6 page.
From the documentation the postback should look like
POST /.../Upload.asp?b_customerId=[O/M1234] HTTP/1.1
Content-length: 12345
Content-type: multipart/form-data; boundary=vxvxv
Host: www.foo.com
--vxvxv
Content-disposition: form-data; name=”File1”; filename=”noColonsSpacesOrAmpersandsInHere”
Content-type: text/xml
<?xml version=”1.0” encoding=”UTF-8”?>
...
<bat:Batch ...
.......
</bat:Batch>
--vxvxv--
I think im having trouble with the boundary characters. I tried setting the boundary in the post data and fiddler shows something similar but I get a page back with the error "Invalid procedure call or argument". the Content-disposition is in the body rather than the header to keep it within the boundaries. Im not sure that is right. Am I setting the boundary the correct way? Can anyone give some guidance on how to do an IE6 style HTTP POST using C# ? Thanks
My Code
data = "--vxvxv" + Environment.NewLine +
"Content-disposition: form-data; name=\"File1\";" + Environment.NewLine +
"filename=\"provideTest.xml\"" + Environment.NewLine +
"Content-type: text/xml" + Environment.NewLine +
#"<?xml version=""1.0"" encoding=""UTF-8""?>" + Environment.NewLine +
data + Environment.NewLine +
"--vxvxv--";
var encoding = ASCIIEncoding.UTF8;
HttpWebRequest request;
var postData = encoding.GetBytes(data);
request = (HttpWebRequest)WebRequest.Create(url);
request.ContentLength = postData.Length;
request.Method = "POST";
request.ContentType = "multipart/form-data; boundary=vxvxv";
request.Host = "www.foo.com";
request.ContentLength = postData.Length;
X509Certificate2Collection certCollect = new X509Certificate2Collection();
X509Certificate2 cert = new X509Certificate2(#"C:\a\cert.pfx", "password");
certCollect.Add(cert);
request.ClientCertificates = certCollect;
using (Stream writeStream = request.GetRequestStream()) {
writeStream.Write(postData, 0, postData.Length); }
WebResponse webResponse = request.GetResponse();
string output = new StreamReader(webResponse.GetResponseStream()).ReadToEnd();
LogEntry.Write("Recieved : " + output);
return output;
Fiddler Output (raw)
POST https://../Upload.asp?b_customerId=%5BO/M1234%5D HTTP/1.1
Content-Type: multipart/form-data; boundary=vxvxv
Host: www.foo.com
Content-Length: 5500
Expect: 100-continue
Connection: Keep-Alive
--vxvxv
Content-disposition: form-data; name="File1";
filename="provideTest.xml"
Content-type: text/xml
<?xml version="1.0" encoding="UTF-8"?>
...SNIP...
</bat:Batch>
--vxvxv--
I think that you have two potential problems:
1) The URL that you are sending formats the b_CustomerId parameter differently than the IE6 implementation. If the site you are targeting does not expect an HTML-encoded value, this could very easily be the source of the error message.
Your request:
Upload.asp?b_customerId=%5BO/M1234%5D
The IE6 request:
Upload.asp?b_customerId=[O/M1234]
In order to fix this issue, you can create a new Url from an overload of the Uri class constructor that has been marked as obsolete, but still works correctly. This overload allows you to specify that the string has already been escaped in the second parameter.
In order to use this constructor, change this line:
request = (HttpWebRequest)WebRequest.Create(url);
to this:
request = (HttpWebRequest)WebRequest.Create(new Uri(url, true));
2) The Content-disposition tag is not formatted the same way in your request as it is in the IE6 request.
Your request:
Content-disposition: form-data; name="File1";
filename="provideTest.xml"
IE6 request:
Content-disposition: form-data; name=”File1”; filename=”noColonsSpacesOrAmpersandsInHere”
This can be resolved by changing these two lines:
"Content-disposition: form-data; name=\"File1\";" + Environment.NewLine +
"filename=\"provideTest.xml\"" + Environment.NewLine +
to:
"Content-disposition: form-data; name=\"File1\"; " +
"filename=\"provideTest.xml\"" + Environment.NewLine +
I have blogged about a way of uploading multiple files using a WebClient and the possibility to send parameters as well. Here's the relevant code:
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; }
}
and then a method to perform the upload:
public byte[] UploadFiles(string address, IEnumerable<UploadFile> files, NameValueCollection values)
{
var request = WebRequest.Create(address);
request.Method = "POST";
var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo);
request.ContentType = "multipart/form-data; boundary=" + boundary;
boundary = "--" + boundary;
using (var requestStream = request.GetRequestStream())
{
// Write the values
foreach (string name in values.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(values[name] + Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
}
// Write the files
foreach (var file in files)
{
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);
buffer = Encoding.ASCII.GetBytes(Environment.NewLine);
requestStream.Write(buffer, 0, buffer.Length);
}
var boundaryBuffer = Encoding.ASCII.GetBytes(boundary + "--");
requestStream.Write(boundaryBuffer, 0, boundaryBuffer.Length);
}
using (var response = request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var stream = new MemoryStream())
{
responseStream.CopyTo(stream);
return stream.ToArray();
}
}
which could be used like so:
using (var stream1 = File.Open("test.txt", FileMode.Open))
using (var stream2 = File.Open("test.xml", FileMode.Open))
using (var stream3 = File.Open("test.pdf", FileMode.Open))
{
var files = new[]
{
new UploadFile
{
Name = "file",
Filename = "test.txt",
ContentType = "text/plain",
Stream = stream1
},
new UploadFile
{
Name = "file",
Filename = "test.xml",
ContentType = "text/xml",
Stream = stream2
},
new UploadFile
{
Name = "file",
Filename = "test.pdf",
ContentType = "application/pdf",
Stream = stream3
}
};
var values = new NameValueCollection
{
{ "key1", "value1" },
{ "key2", "value2" },
{ "key3", "value3" },
};
byte[] result = UploadFiles("http://localhost:1234/upload", files, values);
}
This won't be a complete answer, but you could look at using a socket instead of WebRequest and performing the HTTP request yourself. It seems that the multipart handler on your server is non-conformi g and expects the request to be the same as IE6 would make, so emulating that yourself would be the best approach.
Related
[Basically the same as this guy, unfortunately the thread died before being answered.]WebClient's UploadFile and UploadData not sending same headers (with multipart/form-data)
I can upload a file using the WebClients UploadFile, but I'm unable to upload the same exact file converted to a byte array using UploadData.
Fiddler difference:
On UploadData: Content-Length: 13264
Content-Type: multipart/form-data; boundary=---------------------8d77fde3018f8e5
On UploadFile: Content-Length: 13457
Content-Type: multipart/form-data; boundary=---------------------8d77fdcfcc453c5
Why is this happening? Currently the file i have is stored in memory and not on file, and saving the file locally isn't really an option.
Anyone has any ideas?
EDIT:
var bytes = System.IO.File.ReadAllBytes("dummy.pdf");
using (WebClient client = new WebClient())
{
client.Headers.Add("Access-Token", token);
client.Headers.Add("Client-Secret", clientSecret);
client.UploadFile("website", "dummy.pdf");
}
string boundary = "---------------------" + DateTime.Now.Ticks.ToString("x");
var newLine = Environment.NewLine;
var fileHeaderFormat = "--"+boundary + newLine +
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" + newLine +
"Content-Type: application/octet-stream" + newLine + newLine;
var req = (HttpWebRequest)HttpWebRequest.Create(#"website");
req.Method = WebRequestMethods.Http.Post;
req.ContentType = "multipart/form-data; boundary=" + boundary;
req.Headers.Add("Access-Token", token);
req.Headers.Add("Client-Secret", clientSecret);
req.Headers.GetType().InvokeMember("ChangeInternal",
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
Type.DefaultBinder, req.Headers, new object[] { "Connection", "Keep-Alive" }
);
using (var reqStream = req.GetRequestStream())
{
var reqWriter = new StreamWriter(reqStream);
var tmp = string.Format(fileHeaderFormat, "file", "dummy.pdf");
reqWriter.Write(tmp);
reqWriter.Flush();
reqStream.Write(bytes, 0, bytes.Length);
}
var res = req.GetResponse();
using (var resStream = res.GetResponseStream())
{
var reader = new StreamReader(resStream);
var t = reader.ReadToEnd();
}
I've seen many different 'answers' to this, none of them complete. This is my current code for my upload function. It should be complete enough for discussion. I'm getting a (500) error when attempting to upload a .png file. The .png file gets consumed by the formbytes stream, but when it gets to the actual request on the last line, it throws the error. HELP!
public void Upload(string uri, string filePath)
{
FileInfo fi = new FileInfo(filePath);
string fileType = fi.Extension.Replace(".", "");
string slug = fi.Name.Replace(fi.Extension, "");
string formdataTemplate = "Content-Disposition: form-data; name=\"file\" filename=\"{0}\";\r\nContent-Type: application/octet-stream\r\n\r\n";
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Accept = "application/json";
if (cookies != null)
{
// cookies is a cookie container populated by another process, works for creating ALM requirements
request.CookieContainer = cookies;
}
request.Headers.Add("slug", slug);
string formitem = "";
byte[] formbytes = null;
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(boundarybytes, 0, boundarybytes.Length);
formitem = string.Format(formdataTemplate, Path.GetFileName(filePath));
formbytes = Encoding.UTF8.GetBytes(formitem);
requestStream.Write(formbytes, 0, formbytes.Length);
byte[] buffer = new byte[1024 * 4];
int bytesLeft = 0;
while ((bytesLeft = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
requestStream.Write(buffer, 0, bytesLeft);
}
}
}
//request.Headers.Add(formbytes);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { }
}
The answer is that I had to check-out the requirement to add the attachment. It's a simple post, with no body needed, to :
/rest/domains/[domain]/projects/[project]/requirements/[entityId]/versions/check-out
and you can check-in, also no body needed:
/rest/domains/[domain]/projects/[project]/requirements/[entityId]/versions/check-out
I want to send a message and photo to a channel with my bot in c# 2013.
Message and photo should be sent in one box. Photo in above the message .
i can send a message to the channel successfully but there are 2 problems:
when send photo , this error shows:
The remote server returned an error: (400) Bad Request.
I cannot send a text and photo together in only 1 send.
code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Telegram.Bot;
using Telegram.Bot.Types;
using System.Net;
namespace SendTxt-Photo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string Token = "adasdsadsadsadasds";
string channel_id = "#BestLaptop";
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
using (var stream = File.Open(#"image/1.jpg", FileMode.Open))
{
WebRequest req = WebRequest.Create("https://api.telegram.org/bot" + Token + "/sendMessage?chat_id=" + channel_id + "&text=" + textbox1.text);
req.UseDefaultCredentials = true;
WebRequest req1 = WebRequest.Create("https://api.telegram.org/bot" + Token + "/sendPhoto?chat_id=" + channel_id + "&Photo=" + stream );
req.UseDefaultCredentials = true;
req1.UseDefaultCredentials = true;
var result = req.GetResponse();
req.Abort();
var result1 = req1.GetResponse();
req1.Abort();
}
}
}
}
At first you must know that you send ...&photo=Sistem.IO.FileStream instead your file. It's root cause of bad request. Take a look in debug.
At second as you can see in api documentation sendPhoto method provide three types of photo parameter:
Pass a file_id as String to send a photo that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a photo from the Internet, or upload a new photo using multipart/form-data.
So using multipart/form-data required in your case. It can be simplified by using RestSharp for example like (code was generated by Postman, haven't tested):
var client = new RestClient("https://api.telegram.org/botadasdsadsadsadasds/sendPhoto");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"chat_id\"\r\n\r\n#BestLaptop\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"1.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
At third you can't sent photo above text in one message. For sending text and photo in one message use caption parameter of sendPhoto method. It provide 200 symbols length.
PS Why not using the Telegram.Bot nuget package?
This function is helper to upload file:
public static string UploadFilesToRemoteUrl(HttpWebRequest request, string[] files, NameValueCollection formFields = null)
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
Stream memStream = new System.IO.MemoryStream();
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "--");
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
if (formFields != null)
{
foreach (string key in formFields.Keys)
{
string formitem = string.Format(formdataTemplate, key, formFields[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
}
string headerTemplate =
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
memStream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, "photo", files[i]);
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read))
{
var buffer = new byte[1024];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
}
}
memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
request.ContentLength = memStream.Length;
using (Stream requestStream = request.GetRequestStream())
{
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
}
using (var response = request.GetResponse())
{
Stream stream2 = response.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
return reader2.ReadToEnd();
}
}
Here the code to send file (proxy used for Roscomnadzor) Use your variables instead of msg.GetParam({""}) you'll need chat_id, bot_id,photo and caption. And "proxy" if you need it.
string filePath = msg.GetParam("photo");
string URL = "https://api.telegram.org/bot" + msg.GetParam("bot_id") + "/sendPhoto";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
WebProxy myProxy = new WebProxy(msg.GetParam("proxy"));
myProxy.UseDefaultCredentials = true;
request.Proxy = myProxy;
string[] variable_name = {filePath};
NameValueCollection form = new NameValueCollection();
form["chat_id"] = msg.GetParam("chat_id");
form["caption"] = msg.GetParam("caption");
UploadFilesToRemoteUrl(request, variable_name, form);
I am using this code below to authenticate and upload file to a website, but I am getting an error "Corrupt form data: no leading boundary".
In the Fiddler I see this, ( I see the exact same thing when I upload the file using browser), not sure why I am getting an error when I am doing using C# HttpWebRequest/WebClient
Fiddler Info:
------WebKitFormBoundary9ewWOMyBmk0YAhTL
Content-Disposition: form-data; name="FileSubmitted"; filename="SAMPLE_0001.xls"
Content-Type: application/vnd.ms-excel
------WebKitFormBoundary9ewWOMyBmk0YAhTL
Content-Disposition: form-data; name="FileSubmittedValue"
C:\path\SAMPLE_0001.xls
------WebKitFormBoundary9ewWOMyBmk0YAhTL--
Assumptions:
I hard coded the 'boundary' value, because I am not sure how to get the 'boundary' value after login.
Code: Copied from Stackoverflow
static void Main()
{
NameValueCollection nvCollection = new NameValueCollection();
CookieAwareWebClient webClient = new CookieAwareWebClient();
nvCollection.Clear();
nvCollection["Name"] = "ABC";
nvCollection["Password"] = "XYZ";
//Login to the Site
byte[] responseBytes = webClient.UploadValues("https://www.somesite.com/login.cfm", "POST", nvCollection);
string resultAuthTicket = Encoding.UTF8.GetString(responseBytes);
//Get Cookies
CookieCollection cookies = webClient.CookieContainer.GetCookies(new Uri("https://www.somesite.com/login.cfm"));
//
string URL = "https://www.somesite.com/app/request.cfm";
string boundary = "----WebKitFormBoundary9ewWOMyBmk0YAhTL";
string FilePath = "C:\\Users\\user.name\\Desktop\\SAMPLE_0001.xls";
byte[] fileData = GetMultipartFormData(new Dictionary<string, object>() { { "FileSubmitted", FilePath } }, boundary);
PostForm(URL, "", "", fileData, boundary, cookies);
}
private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
{
Encoding encoding = Encoding.UTF8;
Stream formDataStream = new System.IO.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.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));
needsCLRF = true;
{
string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",
boundary,
param.Key,
param.Value,
"application/vnd.ms-excel");
formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
string postData2 = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\" \r\n\r\n{2}",
boundary,
"FileSubmittedValue",
"C:\\path\\SAMPLE_0001.xls");
formDataStream.Write(encoding.GetBytes(postData2), 0, encoding.GetByteCount(postData2));
}
}
// Add the end of the request. Start with a newline
string footer = "\r\n--" + boundary + "--\r\n";
formDataStream.Write(encoding.GetBytes(footer), 0, encoding.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;
}
private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData, string boundary, CookieCollection cookies)
{
HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
if (request == null)
{
throw new NullReferenceException("request is not a http request");
}
// Set up the request properties.
request.UserAgent = userAgent;
request.ContentLength = formData.Length;
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies);
request.Host = "secure.somesite.com";
request.Referer = String.Format("https://secure.somesite.com/app/request.cfm?CFID={0}&CFTOKEN={1}", cookies[0].Value, cookies[1].Value);
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36";
// Send the form data to the request.
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(formData, 0, formData.Length);
requestStream.Close();
}
try
{
return request.GetResponse() as HttpWebResponse;
}
catch (WebException wex)
{
var pageContent = new StreamReader(wex.Response.GetResponseStream())
.ReadToEnd();
return null;
}
return null;
}
Error:
<head><title>JRun Servlet Error</title></head><h1>500 </h1><body>
<pre>
Corrupt form data: no leading boundary: != ------WebKitFormBoundary9ewWOMyBmk0YAhTL</pre><br><pre>
java.io.IOException: Corrupt form data: no leading boundary: != ------WebKitFormBoundary9ewWOMyBmk0YAhTL
at com.oreilly.servlet.multipart.MultipartParser.<init>(MultipartParser.java:176)
at com.oreilly.servlet.multipart.MultipartParser.<init>(MultipartParser.java:95)
at coldfusion.filter.FormScope.fillMultipart(FormScope.java:170)
at coldfusion.filter.FusionContext.SymTab_initForRequest(FusionContext.java:435)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:33)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:126)
at coldfusion.CfmServlet.service(CfmServlet.java:175)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
at jrun.servlet.FilterChain.service(FilterChain.java:101)
at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
</pre></body>
Don't Knows: Since I copied this source code from Stackoverflow, I don't know if the file really getting uploaded to C:\Path folder on server (look at the Fiddler data).
Update: When I try to upload file using browser I see Content-Length: 49504, but when I try using C# program Content-Length: 385 (Even when I use the same file in both browser and C# program)
Also, when I try now I am getting "No data was received in the uploaded file SAMPLE_0001.xls"
The code is missing this line of code, which is the actual file content.
formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
Thanks all for your help!
I want to keep it as simple as possible -
-We switched from an Godaddy windows hosting to Godaddy linux hosting
-After switching i get internal server error 500 when iam using POST from an c#
program(compact framework) with the content type - multipartformdata,
However i can still use a normal html form that sits on the server to post with no issues.
-Everything worked absolutly fine before the switch! I can still do GET requests,
and even normal(Not multipart/form-data) POST request from my C# app .
Headers and content from the request / response using the code below :
Request headers -
POST /users/test.php HTTP/1.1
Content-Type: multipart/form-data; boundary=----------------------------8d0cb969d25c418
Host: mydomain(i censor)
Content-Length: 403
Expect: 100-continue
Connection: Keep-Alive
Request content -
------------------------------8d0cb969d25c418
Content-Disposition: form-data; name="title";
test
------------------------------8d0cb969d25c418
Content-Disposition: form-data; name="pwd";
testpwd
------------------------------8d0cb969d25c418
Content-Disposition: form-data; name="file"; filename=test.txt
Content-Type: text/html
testfile
------------------------------8d0cb969d25c418
Response headers -
HTTP/1.1 500 Internal Server Error
Date: Fri, 20 Dec 2013 10:32:01 GMT
Server: Apache mod_fcgid/2.3.10-dev
Content-Length: 662
Keep-Alive: timeout=5
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
This is my C# Code(Note - I must use compact framework only) :
openFileDialog1.ShowDialog();
NameValueCollection formsdata = new NameValueCollection();
formsdata.Add("title", textBox3.Text);
formsdata.Add("pwd", textBox4.Text);
string[] names = new string[1] { openFileDialog1.FileName };
UploadFilesToRemoteUrl("http://mydomain/users/writefile.php", names, "notused", formsdata, openFileDialog1.SafeFileName);
and for the method UploadFilesToRemoteUrl -
public static void UploadFilesToRemoteUrl(string url, string[] files, string
logpath, NameValueCollection nvc, string filename)
{
long length = 0;
string boundary = "----------------------------" +
DateTime.Now.Ticks.ToString("x");
HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest2.ContentType = "multipart/form-data; boundary=" +
boundary;
httpWebRequest2.Method = "POST";
httpWebRequest2.KeepAlive = true;
httpWebRequest2.Credentials =
System.Net.CredentialCache.DefaultCredentials;
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
string formitem = string.Format(formdataTemplate, key, nvc[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=" + filename + "\r\n Content-Type: text/html\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
//string header = string.Format(headerTemplate, "file" + i, files[i]);
string header = string.Format(headerTemplate, "file", files[i]);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(files[i], FileMode.Open,
FileAccess.Read);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
memStream.Write(boundarybytes, 0, boundarybytes.Length);
fileStream.Close();
}
httpWebRequest2.ContentLength = memStream.Length;
Stream requestStream = httpWebRequest2.GetRequestStream();
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
WebResponse webResponse2 = httpWebRequest2.GetResponse();
Stream stream2 = webResponse2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
MessageBox.Show(reader2.ReadToEnd());
webResponse2.Close();
httpWebRequest2 = null;
webResponse2 = null;
}
Any help is really highly appreciated!