HTTP Upload vs. SOAP Request (how they are different)

What is the difference between an HTTP Upload and a SOAP Request?

An upload is an HTTP request that uses the multipart/form-data content-type. (All HTTP requests and responses are MIME, and the format of a given request is determined by the content-type.) A SOAP request, on the other hand, has a content-type of text/xml, which means it is composed of a MIME header + body, where the body contains the SOAP XML. Whereas an upload is a multipart MIME structure, where each sub-part contains either the content of a file, or a name/value parameter.

Here are some examples. First a very simple HTTP upload as produced by this C++ fragment:

CkUpload upload;
CkUrl url;

url.ParseUrl("https://www.some-web-server.com/receiveTheUpload.aspx");

upload.put_Hostname(url.host());
upload.put_Path(url.path());
upload.put_Port(url.get_Port());

upload.AddCustomHeader("MyCustomRequestHeader","abc 123");

upload.AddFileReference("TinyA","qa_data/xml/tinyA.xml");

CkByteData uploadData;
upload.UploadToMemory(uploadData);
uploadData.saveFile("qa_output/uploadData1.txt");

The HTTP request (which is MIME, and by the way, and emails are also composed of MIME, so understanding a bit about MIME will do one good because it is so central to Internet technologies..) looks like this:

POST /receiveTheUpload.aspx HTTP/1.1
Host: www.some-web-server.com
User-Agent: ChilkatUpload/3.0 (http://www.chilkatsoft.com/)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Expect: 100-continue
MyCustomRequestHeader: abc 123
Content-Type: multipart/form-data; boundary=---------------------------DD1A174A4121EDFD
Content-Length: 206

-----------------------------DD1A174A4121EDFD
Content-Disposition: form-data; name="TinyA"; filename="tinyA.xml"
Content-Type: text/xml

<tiny>A</tiny>
-----------------------------DD1A174A4121EDFD--

A SOAP XML request, as sent by this fragment of C++ code:

CkHttp http;

http.put_SessionLogFilename("qa_output/xmlPostLog.txt");

// The URL used here is junk and will result in a 404 not found. 
// (We don't care about the response, we
// are only interested in understanding the format of the HTTP request sent.)
// Imagine the XML passed in the 2nd argument is actually a SOAP XML document... 

CkHttpResponse *resp = http.PostXml("http://www.chilkatsoft.com/mywebservice",
    "<tiny>A</tiny>","utf-8");
delete resp;

Looks like this:

(Imagine the XML is actually a SOAP XML document..)

POST /mywebservice HTTP/1.1
Content-Type: text/xml
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip
Host: www.chilkatsoft.com
Content-Length: 14

<tiny>A</tiny>

An HTTP upload containing two file is produced by this fragment of code:

CkUpload upload;
CkUrl url;

url.ParseUrl("https://www.some-web-server.com/receiveTheUpload.aspx");

upload.put_Hostname(url.host());
upload.put_Path(url.path());
upload.put_Port(url.get_Port());

upload.AddCustomHeader("MyCustomRequestHeader","abc 123");

upload.AddFileReference("TinyA","qa_data/xml/tinyA.xml");
upload.AddFileReference("TinyB","qa_data/xml/tinyB.xml");

CkByteData uploadData;
upload.UploadToMemory(uploadData);
uploadData.saveFile("qa_output/uploadData2.txt");

And the HTTP request looks like this:

POST /receiveTheUpload.aspx HTTP/1.1
Host: www.some-web-server.com
User-Agent: ChilkatUpload/3.0 (http://www.chilkatsoft.com/)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Expect: 100-continue
MyCustomRequestHeader: abc 123
Content-Type: multipart/form-data; boundary=---------------------------6F87F47E0974A38B
Content-Length: 363

-----------------------------6F87F47E0974A38B
Content-Disposition: form-data; name="TinyA"; filename="tinyA.xml"
Content-Type: text/xml

<tiny>A</tiny>
-----------------------------6F87F47E0974A38B
Content-Disposition: form-data; name="TinyB"; filename="tinyB.xml"
Content-Type: text/xml

<tiny>B</tiny>
-----------------------------6F87F47E0974A38B--

Finally, an HTTP upload with multiple files and a few name/value params is produced by this C++ fragment:

CkUpload upload;

CkUrl url;

url.ParseUrl("https://www.some-web-server.com/receiveTheUpload.aspx");

upload.put_Hostname(url.host());
upload.put_Path(url.path());
upload.put_Port(url.get_Port());

upload.AddCustomHeader("MyCustomRequestHeader","abc 123");

upload.AddParam("ParamA","This is the value for param A");
upload.AddParam("ParamB","This is the value for param B");

upload.AddFileReference("TinyA","qa_data/xml/tinyA.xml");
upload.AddFileReference("TinyB","qa_data/xml/tinyB.xml");

CkByteData uploadData;
upload.UploadToMemory(uploadData);
uploadData.saveFile("qa_output/uploadData3.txt");

And the HTTP request looks like this:

POST /receiveTheUpload.aspx HTTP/1.1
Host: www.some-web-server.com
User-Agent: ChilkatUpload/3.0 (http://www.chilkatsoft.com/)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: keep-alive
Expect: 100-continue
MyCustomRequestHeader: abc 123
Content-Type: multipart/form-data; boundary=---------------------------EFC8C527CC836355
Content-Length: 617

-----------------------------EFC8C527CC836355
Content-Disposition: form-data; name="ParamA"

This is the value for param A
-----------------------------EFC8C527CC836355
Content-Disposition: form-data; name="ParamB"

This is the value for param B
-----------------------------EFC8C527CC836355
Content-Disposition: form-data; name="TinyA"; filename="tinyA.xml"
Content-Type: text/xml

<tiny>A</tiny>
-----------------------------EFC8C527CC836355
Content-Disposition: form-data; name="TinyB"; filename="tinyB.xml"
Content-Type: text/xml

<tiny>B</tiny>
-----------------------------EFC8C527CC836355--

Upload from ASP code to FTP Server

I get the following support problem about once per week from ASP developers:

The ASP developer wants to upload a file from the client computer where the browser is running, to an FTP server.  He writes ASP code to do the FTP upload, but cannot understand why the file is not found.  The thing the ASP developer doesn’t realize is that his ASP code runs on the web server, not on the client computer where the browser is running.

When I detect this misunderstanding, I’ll be pointing you to this blog post.  Here’s a summary of what you should know:

  1. Your browser, such as Internet Explorer, is running on computer “A”.
  2. The browser communicates with a web server running on computer “B”.
  3. Your ASP code runs within the web server’s worker process on computer “B”.
  4. Your FTP server runs on computer “C”.
  5. Your ASP code (running on computer “B”) is trying to upload a file to the FTP server on computer “C”.  Therefore, it is trying to transfer a file from “B” to “C”.
  6. If you want to upload a file from computer “A” to the FTP server (computer “C”), you need to first do an HTTP upload via HTML using a Form with “<input type=”file” …”.  This uploads from the computer where the browser runs to the web server. Your ASP code then uploads the code from the web server to the FTP server.

FTP Upload Files to Web Server?

Question:
We are trying out the FTP2 ActiveX component for ASP. What we need to do is
have people be able to upload files to the web server over the Internet. Is
this component able to do this – or can it only FTP files that are already on the
web server?

Answer:
This is a common question. The need is to upload files from the user’s computer (i.e. the computer where the browser is running) to the web server. You should remember that your ASP code is running on the server (not on the computer where the browser is running). Therefore, any code within your ASP will only have access to the files on the web server. What you really want is to do a simple HTTP file upload from the browser. You’ll need to provide both client-side and server-side code to implement the HTTP upload. The client-side is extremely easy — you simply create a form with “file” type input tags:

<html>
<body>
<form method="POST" enctype="multipart/form-data" action = "http://www.mywebserver.com/ReceiveUpload.aspx" >
<input name=attach1 type=file size=20><br>
<input name=attach2 type=file size=20><br>
<input type=submit value="Upload">
</form>
</body>
</html>

The above form uploads two files, and also sends a few extra (non-file) form fields. To upload a single file, simply remove one of the “input” HTML tags.

Receiving the upload on the server-side requires programming.  It can be done in classic ASP, ASP.NET, Perl, a C++ CGI, etc.

Here are examples for classic ASP and ASP.NET:

Receive HTTP Upload Files in Classic ASP

Receive HTTP Uploads directly into memory in Classic ASP

Receive Upload + additional form fields in Classic ASP

Complete ASP.NET (C#) HTTP Upload Example

IIS 6.0 Upload Size Limit

The AspMaxRequestEntityAllowed Metabase Property (IIS 6.0) specifies the maximum number of bytes allowed in the entity body of an ASP request. The default value is 2MB. To upload files greater than this size, this IIS metabase property must be changed on the server.

File Upload Limits in IIS7 – Increasing the Size Limit

A web application running in IIS7 on Windows Server 2008 will reject any upload that is larger than 30MB. This is the default size limit for IIS7. To increase the maximum file size, add the following code to <system.webServer> in the web.config file:
(This example sets the limit to 500MB)

<security>
 <requestFiltering>
  <requestLimits maxAllowedContentLength=”500000000″ />
 </requestFiltering>
</security>

You must restart IIS for the setting to take effect.

ASP Upload Script – Receiving Form Text Fields with File Uploads

The Chilkat Upload ActiveX component (which is entirely freeware) provides the capability to receive both form text items as well as file uploads in a single HTTP POST. This post provides an example. First we show the HTML FORM with both text and file input fields. Then we show the ASP script to receive the POST.

More information about the Chilkat ASP Upload component.

The HTML form to send the upload w/ additional form parameters:

<html>
<head>
<title>ASP Upload with Additional Form Parameters</title>
<body>
<h1>ASP Upload with Additional Form Parameters</h1>

<p>Demonstrates how to pass form parameters in addition to uploading a file.  The ASP code that receives this POST will use the form parameters for the Subject, From, To, and Body of an email.  The uploaded file will be attached to the email.</p>

<form method="POST" enctype="multipart/form-data" action = "http://localhost/aspEmailUpload.asp" >

Subject: <input name="subject" type="text" size=40><br><br>
From Email: <input name="fromAddr" type="text" size=40><br><br>
To Email: <input name="toAddr" type="text" size=40><br><br>

<textarea name="emailBody" rows="6" cols="40">
Type the plain-text body of your email here...
</textarea><br><br>

Add a file attachment to the email:<br>
<input name=attach1 type=file size=20><br><br>

Attachment Filename in Email: <input name="attachFname" type="text" size=40><br><br>

<input type=submit value="Upload and Email">
</form> 

</body>
</html>

ASP Script to Receive the Upload:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<%

'  The Chilkat ASP Upload component is freeware.
'  The UploadRcv object receives uploads in ASP.
'  It can be used to save uploaded files to the web server,
'  or to save directly to memory for immediate access.
'  This example streams an uploaded file into memory.
set receiver = Server.CreateObject("Chilkat.UploadRcv")

'  Set a timeout just in case something hangs
'  This is a 20-second timeout:
receiver.IdleTimeoutMs = 20000

'  Consume the upload.  Files are streamed to the UploadDir
success = receiver.Consume()

If (success = 1) And (receiver.NumFilesReceived > 0) Then

    ' The Chilkat Upload component is freeware.  
    ' For demonstration purposes, this example receives the upload 
    ' form params and file and uses the data to send an email.
    ' The Chilkat Email component is not freeware.
    
	'  The mailman object is used for sending and receiving email.
	set mailman = Server.CreateObject("Chilkat.MailMan2")

	'  Any string argument automatically begins the 30-day trial.
	success = mailman.UnlockComponent("30-day trial")
	If (success = 1) Then

		'  Set the SMTP server.
		mailman.SmtpHost = "smtp.chilkatsoft.com"

		'  Set the SMTP login/password (if required)
		mailman.SmtpUsername = "myLogin"
		mailman.SmtpPassword = "myPassword"

		'  Create a new email object
		set email = Server.CreateObject("Chilkat.Email2")

		' We don't use Request.Form.  Instead use receiver.GetParam
		' because the receiver object received the HTTP request.
		email.Subject = receiver.GetParam("subject")
		
		Response.Write "Subject: " & email.Subject & "<p>"
		
		email.Body = receiver.GetParam("emailBody")
		email.From = receiver.GetParam("fromAddr")
		email.AddMultipleTo receiver.GetParam("toAddr")
		
		' Add the uploaded file as an attachment:
		email.AddDataAttachment receiver.GetFileData(0), receiver.GetParam("attachFname")

		'  Call SendEmail to connect to the SMTP server and send.
		'  The connection (i.e. session) to the SMTP server remains
		'  open so that subsequent SendEmail calls may use the
		'  same connection.
		success = mailman.SendEmail(email)
		If (success = 1) Then
			'  Some SMTP servers do not actually send the email until
			'  the connection is closed.  In these cases, it is necessary to
			'  call CloseSmtpConnection for the mail to be  sent.
			'  Most SMTP servers send the email immediately, and it is
			'  not required to close the connection.  We'll close it here
			'  for the example:
			success = mailman.CloseSmtpConnection()
			If (success <> 1) Then
			    Response.Write "Connection to SMTP server not closed cleanly." & "<br>"
			End If

			Response.Write "Mail Sent!" & "<br>"
		else
		    Response.Write mailman.LastErrorText & "<br>"
		End If
	
	else
	    Response.Write "Component unlock failed"
	end if
	
else 
	Response.Write "Failed to receive upload."
end if



%>
</body>
</html>