Uploading files to a web server over HTTP is simple, but requires user code at both the client for sending and at the server for receiving. The most simple client-side code for doing HTTP upload is an HTML form:
<form method="POST" enctype="multipart/form-data" action = "https://www.example.com/receiveUpload.asp" >
<input name=attach1 type=file size=20>
<input type=submit value="Upload">
</form>
To upload more than one file, simply add additional inputs, such as this:
<form method="POST" enctype="multipart/form-data" action = "https://www.example.com/receiveUpload.asp" >
<input name=attach1 type=file size=20><br />
<input name=attach2 type=file size=20><br />
<input type=submit value="Upload">
</form>
The server-side code must process the HTTP upload and receive the file(s) — in any way it wishes. There are many ways to do it — in ASP.NET, Perl, ASP, JSP, PHP, C++, etc.
This simple C++ CGI using the Chilkat CkCGI class (which is freeware) provides an example.
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include "include/CkString.h"
#include "include/CkCGI.h"
void ReceiveUpload(CkString &htmlResponse)
{
CkCGI cgi;
cgi.put_DebugLogFilename("debugLog.txt");
// The UploadDir property indicates the directory where uploads will be deposited.
// This line is commented out because this example uses the special "<null>" string
// to discard the data it receives. (see below)
//cgi.put_UploadDir("uploads");
// The "<null>" string indicates that CkCGI should simply discard the bytes
// it receives during an upload.
cgi.put_UploadDir("<null>");
// If StreamToUploadDir is true, uploads are streamed to the UploadDir (unless UploadDir
// is set to "<null>" in which case all received bytes are discarded and no files are created.
// Because the upload is streamed, any size file is supported.
cgi.put_StreamToUploadDir(true);
// You may limit the size of uploads by setting a limit in KB.
cgi.put_SizeLimitKB(1024); // 1MB limit
// Receiving the upload and (potentially) streaming to files occurs within ReadRequest.
bool b = cgi.ReadRequest();
if (b)
{
// If successful, form the response.
htmlResponse.setString("<html><body>");
htmlResponse.append("<p>Success! These files were received:</p><p>");
int n = cgi.get_NumUploadFiles();
int i;
for (i=0; i<n; i++)
{
htmlResponse.append(cgi.getUploadFilename(i));
htmlResponse.append("<br>");
}
htmlResponse.append("</p></body></html>");
}
else
{
htmlResponse.setString("<html><body><p>ReadRequest Failed!</p>");
htmlResponse.append(cgi.lastErrorHtml());
htmlResponse.append("</body></html>");
}
}
int main(int argc, char* argv[])
{
// Make sure stdout is binary so line-endings aren't modified
// when calling printf.
setmode(fileno(stdout), O_BINARY);
CkString html;
ReceiveUpload(html);
printf("Content-type: text/html; charset=utf-8\n");
CkString currentDate;
currentDate.appendCurrentDateRfc822();
printf("Last-Modified: %s\n",currentDate.getString());
// Add some additional headers...
printf("Cache-Control: private, s-maxage=0, max-age=0, must-revalidate\n");
printf("Connection: close\n");
printf("Content-Length: %d\n\n",html.getSizeUtf8());
// Output the HTTP response body.
fwrite(html.getUtf8(),html.getSizeUtf8(),1,stdout);
return 0;
}
The best way to get your HTTP upload solution working is to test each side (client vs. server) independently. To test the server, use an HTML form as shown above to upload a file. The browser, whether it be FireFox or Internet Explorer, will surely send a valid HTTP upload to your server. You can work out any problems with the server-side code before testing the client-side code. You can test your client-side code by uploading test files to a known public server that accepts HTTP uploads.
VB.NET HTTP Upload Sample with Progress Monitoring and Abort Capability
Here’s a VB.NET example that uses the Chilkat Upload (freeware) component to upload a file from a VB.NET application:
Private WithEvents upload As Chilkat.Upload
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
upload = New Chilkat.Upload()
' Make sure the EnableEvents property is set to true, otherwise we
' won't receive event callbacks.
upload.EnableEvents = True
' Call AbortCheck every 100 milliseconds.
upload.HeartbeatMs = 100
' To upload more than one file, call AddFileReference multiple times --
' once for each file to be uploaded.
' The formElementName is arbitrary, and can be anything.
Dim formElementName As String = "file1"
' The localFilename is a file that exists on your local filesystem.
Dim localFilename As String = "hamlet.xml"
upload.AddFileReference(formElementName, localFilename)
' The Hostname and Path properties specify the server-side
' page/program/script/CGI that will recieve and process the upload.
upload.Hostname = "www.example.com"
upload.Path = "/receiveUpload.asp"
' The BlockingUpload call does not return until all the files have been
' uploaded (or an error occurs or the upload is aborted by the application).
Dim success As Boolean = upload.BlockingUpload()
If success = False Then
textBox1.Text = upload.LastErrorText
Else
' When BlockingUpload returns true, it indicates that the files/data have
' been uploaded and an HTTP response status indicating success was
' received. If the success/failure of an uploaded is indicated by
' a message in the HTTP response body, you may access it via
' the ResponseBody property (which is a byte array).
textBox1.Text = System.Text.UTF8Encoding.UTF8.GetString(upload.ResponseBody)
MessageBox.Show("Success!")
End If
End Sub
' The Chilkat.Upload.HeartbeatMs property determines the interval at which
' AbortCheck events are called. If HeartbeatMs is set to 0 (the default),
' then no AbortCheck events are called. This example sets the HeartbeatMs = 100
' milliseconds.
Private Sub upload_OnAbortCheck(ByVal sender As Object, ByVal args As Chilkat.AbortCheckEventArgs) Handles upload.OnAbortCheck
' Update progressBar2 so we can visually see the heartbeat.
If (ProgressBar2.Value > 90) Then
ProgressBar2.Value = 0
Else
ProgressBar2.Value += 10
End If
' Handle UI events to keep the user-interface responsive.
System.Windows.Forms.Application.DoEvents()
' To abort the upload while in progress, set the
' args.Abort property = true, like this:
' args.Abort = true;
End Sub
' Progress monitor callback -- called each time the percentage completion
' updates to a larger value.
Private Sub upload_OnPercentDone(ByVal sender As Object, ByVal args As Chilkat.PercentDoneEventArgs) Handles upload.OnPercentDone
' args.PercentDone is an integer value between 1 and 100.
ProgressBar1.Value = args.PercentDone
End Sub