Introduction
One of the most useful extensions to the HTTP protocol, is the ability to use it to upload files. Although, compared to FTP it is somewhat limited, all that is required to make use of HTTP file uploads is access to a web browser.
Transferring files using HTTP is generally safer than FTP as the data sent to the server can be carefully scrutinised before the commitment is made to store / use it. For this reason it is ideal in client/server applications which regularly need to transfer data over the Internet.
The following application, demonstrates how to upload files to a web server using Visual Basic, with the help of the winsock control. In order to add the Winsock Control to your VB6 application, right click on the tool box, select components from the menu and check the box "Microsoft Winsock Control".
This mimics what a web browser does when you upload a file to a site via a web form.
A Bit about HTTP
The Winsock control enables you to establish a connection to another computer using either TCP / UDP and transfer data over that connection. HTTP (Hypertext Transfer Protocol) is used to request and send data to web resources and it is up to the programmer to construct the HTTP request and parse the response.
The file upload application uses a HTTP POST request to send the file in the form of a multi part HTTP request. This is explained fully in RFC 1867
Using the Demo Application
The demo application allows you to enter a URL and choose the file which you wish to upload. You must give the file a name and an MIME type; a list of MIME types for particular file extensions can be found here.
Pressing the upload button sends the HTTP request containing the data from the file which you have chosen.
Like I mentioned earlier HTTP file uploads are useful in client / server applications. So, I have made a script which will take file uploads to demonstrate how the application works, it also has a web interface:
The files which have been uploaded can be found here, it is clear that there is no conceivable difference between files uploaded via VB and via a web browser. The means in which the server gets the data is transparent.
Everyone seems to want the source code for the PHP files. So, here they are.
The post_dump.php file simply loops through all the posted variables and files and displays information on them. It saves the files in another directory, so to use it you need to create two directories:
uploaded_files uploaded_files/files
post_dump.php
PHP Code:
<?php
/* check for and loop through uploaded files */
foreach ($_FILES as $name => $info) {
/* chekc the file has a valid name */
if (($info['name'] != 'ht.access' &&
substr($info['name'], 0,1) != '.' &&
$info['name'] != 'allowed_files')) {
/* attempt to move the file to the uploaded_files directory */
if (@move_uploaded_file($info['tmp_name'], "uploaded_files/files/{$info['name']}")) {
/* get the contenst of the array of files */
$file_arrays = @unserialize(@file_get_contents('uploaded_files/allowed_files'));
/* if there are more already 5 files, remove the oldest item fomr the array
* and delete it
*/
if (count(@$file_arrays['files']) == 5) {
$name = array_shift($file_arrays['files']);
The uploaded_files.php file, displays or allows the user to download last 5 uploaded files.
uploaded_files.php
PHP Code:
<?php
/* load the file containg the list of uploaded files in to an array */
$file_arrays = @unserialize(@file_get_contents('uploaded_files/allowed_files'));
/* check the data was loaded successfully - if not, create an empty array */
if (!is_array($file_arrays)) {
$file_arrays = array('files' => array(), 'types' => array());
}
/* check for the existance of a file variable in the queery string
* if its there, this contains the name of the file to be downlaoded
*/
if (isset($_GET['file'])) {
$file = $_GET['file'];
/* check the file is in the array retrieved from the file */
if (in_array($file, @$file_arrays['files'])) {
/* get the Content-Type of the file */
header('Content-Type: ' . $file_arrays['types'][$file]);
header('Content-Disposition: attachment; filename="' . $file . '"');
This programs are working some how okey, but when I try to use the documents (JPG pictures or any other) online (meaning on a web page or by direct access to it from a web folder,) It just doesn't work. I can not use the files online. Why? Is there any whay to do it, or fix it. I have being trying all kinds of things: change mime type, etc. But still nothing. I will apreciate any help.
Last edited by joechez; Jun 26th, 2005 at 09:52 AM.
Can you clarify what the problem is? - Is it with the server scripts or the example program? Do you get any error messages or is the file just messed up?
I just want to use the uploaded pictures on my website, but they just don't work. If I upload manually using ftp they work just fine. But if I use the script, they don't. Then using the script, I uploaded some pictures (to try out) and downloaded them using ftp. Then uploaded them againg using ftp, and they didn't show up. So, something happend with the pictures using the script. I try other documents also with the same results.
Yes! I have created the needed folders. As I said the script is working. I can upload and download files. But the files get corrupted or something because after doing an upload, they just don't work on regular web pages. I think the attributes of the files are changing or something.
Yeep! The files work okey just changing the attributes to public read and to group read. Still looking forward to transffer variables at the same time using VB6.
HTTPs is HTTP tunneled through SSL. Unfortunatly this is vastly more complicated than a standard unencrypted HTTP connection and somthing which I haven't got the time or the knowledge to do at the moment.
Even i am struggling with uploading files for https sites using vb 6.0.
If anybody gets the solution don't forget to post it here..Also i am looking for this solution very urgently...so pls pls post it asap.
The PHP and VB6 code posted here works really well.
I was just wondering if it would be possible to generalize it to do what I would call "custom folders" (on the server).
I would like to be able to upload just one licence file to a few dozen different folders (one per client). The version of the file is different for each folder.
It would nice to be able to put a loop around the VB6 upload code to make this happen.
But I don't know enough about the methodology used in the current PHP and VB6 code to do this.
anyone here can upload jpg, doc, zip... by this program? I have tried many time and can't success...
But I found that there are no problem when uploading plain text file(txt).
Thank for your reply and your great program first!!
After many times of try and error, I found that it can upload jpg under ENGLISH WinXP, but not in CHINESE WinXP.
for CHINESE WinXP:
There are no error when uploading jpg file, but when I try to download the jpg file from server, I found that the content of jpg is changed and it can't be opened again. May be it is becasue of the encoding problems?
Hi!, in first place let me thank you for share your code visualAd, second a few questions about it:
1)Could your code work with "multipart/form-data" header type?
2)Wich is the max size of the file that can effectively be send?, despiting the servers limitations.
3)How necessary is to do it with winsock.ocx?, it's difficult to do it through winsocks APIs?, does need winsock.ocx be packed along the aplication?
4)Could your code be reproducible with Wininet APIs?
Thanks in advance. Glad to see that someone is sharing this kind of hard to find but high usable code.
1)Could your code work with "multipart/form-data" header type?
What do you mean? It uses the multipart/form-data header in the HTTP request and sends the HTTP request as a multipart document.
2)Wich is the max size of the file that can effectively be send?, despiting the servers limitations.
I am not sure probably the size of a VB string 64k. However, with anything bigger, VB should use swap or other mechanisms to handle the string. I am no VB guru so cannot say for sure.
3)How necessary is to do it with winsock.ocx?, it's difficult to do it through winsocks APIs?, does need winsock.ocx be packed along the aplication?
In theory the ocx should be included. If not, you need to ensure that the control is installed on the OS you are running the program on and hope that if it is installed the version is compatible withh the one you've used.
Winsock is included by default from windows 98+, so I would imagain you'd be quite safe.
4)Could your code be reproducible with Wininet APIs?
I should hope so, as this is exaclty what the Winsock control is a wrapper for
I am not sure probably the size of a VB string 64k. However, with anything bigger, VB should use swap or other mechanisms to handle the string. I am no VB guru so cannot say for sure.in the HTTP request and sends the HTTP request as a multipart document.
Ok, lets say I want to send a 500KBs file, supossing that limit is 64KB, I should use a string class or there's a way to send chunks of data at time?
Originally Posted by visualAd
In theory the ocx should be included. If not, you need to ensure that the control is installed on the OS you are running the program on and hope that if it is installed the version is compatible withh the one you've used.
Winsock is included by default from windows 98+, so I would imagain you'd be quite safe.
So it will be ok for most cases to do it with winsock.ocx rather than directly calls to winsock.dll?
Originally Posted by visualAd
I should hope so, as this is exaclty what the Winsock control is a wrapper for
What if I need to send more data in the form. Like two other input type="text" in the same form to autenticate the user that is sending the file??? Please help.
I'll have a look at modifying the app to include other variables, it is easy enough to modify by yourself however. Also, have a look at the demo app for sending GET/POST HTTP requests.
You need to authenticate yourself using NTLM (Microsoft Windows NT LAN Manager) authentication. It is possible to do this in VB but involves a lot of byte shifting and code.
thanks 4 ur reply visualAd,
pls gimme more detail, how to do so..in policy setting?
im using winxp as webserver(just for development)..
im going to host my webserver at hosting company...
what do i need to tell them to do?
ill buy u a pasta then..hehe..
NTLM is a challenge response protocol. That means the client needs to make a connection containing a challenge and the server makes the response. No user name and password are ever transmitted to the server - the authentication takes place with the domain controller.
Like I say. I have never written an NTLM authenticator in VB and I do not plan to either. That doesn't mean the its not possible, just that its a complex and time consuming task.
If you want to do it yourself here is a detailed specification.
thanks a lot visualAd,
it sound quite hard for that coding...
me either didnt plan to do so...hehe...
im better choose another solution...
im planning to update my sql server directly from my vb local client instead of upload the file then update at the server.
thanks a lot visualAd,
it sound quite hard for that coding...
me either didnt plan to do so...hehe...
im better choose another solution...
im planning to update my sql server directly from my vb local client instead of upload the file then update at the server.
which one is better in terms of reliability?
Hi, If you want add support for http authentication you could add that line in the source:
First of all, I want to thank you for the code. I've been using it for a while and it works great.
Now for my question. Has anyone used a progress bar with the winsock control for uploading files? I'm new to progress bars and want to add one to this code for my program users. Any suggestions, refrences or code would be greatly appreciated.
Hey Visual,
any idea how to modify this code for imagesack.us or similar sites ? These sites redirects to another page (which contains the new links) after uploading.
I tried to upload google2.gif to imagesack usin your code and got this:
Upload URL:
Code:
tried these two:
http://www.imageshack.us/transload.php
http://imageshack.us/ie.php
HTTP/1.0 302 Found
Connection: close
X-Powered-By: PHP/4.4.2
location: http://www.imageshack.us/
Content-type: text/html
Content-Length: 0
Date: Mon, 18 Dec 2006 19:33:19 GMT
Server: lighttpd/1.4.8
1. How do I get the new links of uploade file ?
2. What changes need to be made for registered users ? (Imagesack doesn't allow image deletion for unregistered users)
Last edited by iPrank; Dec 18th, 2006 at 02:55 PM.
Sorry for the confusion. I shouldn't have said 'redirection'.
I tried to mean, when you finish uploading files in imagesack (or YahooMail) they opens a new page that contains URL of the newly uploaded file. (In case of YMail, it is the 'finish attatching file and continue to message' page.)
Getting the HTML of this 'uploading-finished-and-here-is-your-URL' page is necessary. Without it I can't get URL of my own images.
When I tried to mix Visual's and VBIP's code, I got this as 'new URL'.
Code:
http://www.imageshack.us/2 Found
and there is still my second question. How to login to that site with Winsock and upload to that account. (OK, I can use Webbrowser control, but that would be slow.)
[I need this 'cause I want to make a smily collection app like the one Static was making, but want to store the images in ImageSack for easier sharing]
Last edited by iPrank; Dec 18th, 2006 at 11:53 PM.
You need to have cookies enabled for that and also it returns a 302(temporarily moved) which means it is not handling the redirects(not exactly redirects but kinda) properly.
I don't how far i can help you out but i can suggest these:
Thanks for such a wonderful script. How do I cite you as a credit for when I use it?
I got this error:
HTTP/1.1 406 Not Acceptable
Date: Thu, 08 Feb 2007 19:12:41 GMT
Server: Apache/1.3.37 (Unix) mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 FrontPage/5.0.2.2635.SR1.2 mod_ssl/2.8.28 OpenSSL/0.9.7a PHP-CGI/0.1b
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>406 Not Acceptable</TITLE>
</HEAD><BODY>
<H1>Not Acceptable</H1>
An appropriate representation of the requested resource /politicstestresults/post_dump.php could not be found on this server.<P>
<HR>
<ADDRESS>Apache/1.3.37 Server at www.kelceycoe.com Port 80</ADDRESS>
</BODY></HTML>
I've uploaded the files to my upload directory as shown, and chomodded the directory and php files as 777. Is that right or am I doing something way wrong? Thanks.
Last edited by kelceycoe; Feb 8th, 2007 at 02:14 PM.