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--