Jump to content

Downloading file from internet

- - - - -

  • Please log in to reply
11 replies to this topic

#1
Kuto

Kuto

    Learning Programmer

  • Members
  • PipPipPip
  • 49 posts
Hi guys, i need to download files with my own program, i want to write only "file url" and then my program must download it from internet.

I have tried URLDownloadToFile() function but i dont have urlmon.h and urlmon.lib in my library and in my system also i dont have urlmon.dll file :\

Anyway i downloaded urlmon.dll file and tried to get address of URLDownloadToFile function by using GetProcAddress and LoadLibrary functions. Its working now but its not portable.

I also found a code in internet and i tried it but doesnt work . This is my code with URLDownloadToFile api.
#include <windows.h>

#include <stdio.h>


HRESULT (*_URLDownloadToFile)(  

    LPUNKNOWN pCaller,

    LPCTSTR szURL,

    LPCTSTR szFileName,

    DWORD dwReserved,

    void* lpfnCB

	);


int main(){


	_URLDownloadToFile = GetProcAddress(LoadLibrary("urlmon.dll"),"URLDownloadToFileA");


	printf("%X",_URLDownloadToFile);

	_URLDownloadToFile(	NULL,"http://www.lib.berkeley.edu/TeachingLib/Guides/Internet/limiting.pdf", 

						"C:\\asd.pdf", 0, NULL);


	

	getchar();

	return 0;

}

This code i found on internet.

#include <windows.h>

#include <wininet.h>


typedef PVOID HINTERNET ;  


typedef HINTERNET (WINAPI *InetOpenA)(LPCTSTR , char* ,char*,char* ,char* ); //InterNetOpenA

typedef HINTERNET (WINAPI *InetOpenUrlA) (HINTERNET, LPCSTR, char* ,char* ,char* ,char* ); //InternetOpenUrlA

typedef BOOL (WINAPI *InetReadFile) (HINTERNET, LPVOID , DWORD , LPDWORD); //InternetReadFileA

typedef HANDLE (WINAPI *CreatFile) (LPCTSTR,int,int,int,int,int,int); //CreateFileA

typedef BOOL (WINAPI *WritFile) (HANDLE,LPCVOID,int,LPDWORD,int); //WriteFileA


BOOL D_File(char* FromHere)

{

    HINTERNET            InternetHandle;

    HINTERNET            UrlHandle;

    HANDLE                FileHandle;

    unsigned long        BytesNext = 1;

    unsigned long        BytesWritten = 0;

    char                Buffer[2048];


char *SaveFile = "D:\\File.pdf"; //File Destination


// Opening page, with File Save Destination

    InternetHandle = InternetOpen(SaveFile, 0, 0, 0, 0);


    if(InternetHandle != 0)

    {

        UrlHandle = InternetOpenUrl(InternetHandle, FromHere, 0, 0, 0, 0);  //Connectin to your File

        FileHandle = CreateFile(SaveFile, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, 0); //Creating File to spec. Destination, with File Attributes.

     

            while(BytesNext != 0)

            {

                InternetReadFile(UrlHandle, Buffer, sizeof(Buffer), &BytesNext);

                WriteFile(FileHandle, Buffer, BytesNext, &BytesWritten, 0);  //Writing bytes to File

            }


            CloseHandle(FileHandle);

            CloseHandle(UrlHandle);

            CloseHandle(InternetHandle);

        

    }


    return FALSE;

}



int main() {

    D_File("http://www.lib.berkeley.edu/TeachingLib/Guides/Internet/limiting.pdf"); //Your URL Here

return 0;

}

I know socket programming, i can download any web page by using Get methot etc. But i want to download anyfile from internet also by using only winsock library. Can i do that? is there any way?

#2
mnirahd

mnirahd

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 330 posts
Hi,

A quick solution to have a cross plateform working solution is to Use libCurl to download/upload your files over http:

a working code example to download file is


#define CURL_STATICLIB

#include <stdio.h>

#include <curl/curl.h>

#include <curl/types.h>

#include <curl/easy.h>

#include <string>


size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {

    size_t written;

    written = fwrite(ptr, size, nmemb, stream);

    return written;

}


int main(void) {

    CURL *pCurl;

    FILE *fptr;

    CURLcode codes;

    char *url = "http://yourhost/aaa.txt";

    char outfilename[256] = "C:\\downloadedfile.txt";

    pCurl = curl_easy_init();

    if (pCurl) {

        fptr = fopen(outfilename,"wb");

        curl_easy_setopt(pCurl, CURLOPT_URL, url);

        curl_easy_setopt(pCurl,, CURLOPT_WRITEFUNCTION, write_data);

        curl_easy_setopt(pCurl,, CURLOPT_WRITEDATA, fptr);

        res = curl_easy_perform(pCurl);

        curl_easy_cleanup(pCurl);

        fclose(fptr);

    }

    return 0;

}



I hope that helps! Let me know if you thinking to use LibCurl: i can provide you lib/dll for this!

Munir

#3
mebob

mebob

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 490 posts
Well, it is possible to just use Winsock, but you will have to process all the HTTP headers, which I imagine isn't very simple.
Latinamne loqueris?

#4
Kuto

Kuto

    Learning Programmer

  • Members
  • PipPipPip
  • 49 posts
@mnirahd thank you for replying, but i dont want to use an external library, thats why i dont use also urlmon.dll. i want to use only winsock functions.
@mebob, i actually dont know http or ftp headers well, but this is application layer right? no need to use raw sockets, so i can learn it, only raw socket make me crazy coz it2s never working :)

So i will research about http headers or methods to download anyfile from internet, but maybe i need to learn about ftp, not http?

when we wanna download a file like that, (www.example.com/exmple.exe) if we click the link, which commands browser send to the server? Http or ftp commands?

Actually i dont know anything about http or ftp protocols, just i want to download a file from an internet server but only by using winsock apis. so im open to alll suggestions.

#5
sam_coder

sam_coder

    Programming Expert

  • Members
  • PipPipPipPipPipPip
  • 372 posts
in the most basic scenario, the headers do not have to be very complicated at all

when you establish a connection, you're going to want to issue an HTTP GET request
GET /file HTTP/1.1\r\n
host: www.whatever.com\r\n
\r\n


you can enter additional headers, (like host), such as user-agent (you can try this on telnet, just replace \r\n with a return stroke)

but the libCurl idea is a much more robust solution.

If you're going to attempt this with sockets, you will at some point have to deal with things like authentication, https transport etc.

#6
mnirahd

mnirahd

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 330 posts
Hi,

In order to use winsock function and download a file from internet: you must be familiar with Http protocol. In order to download a file you must prepare a valid http request header: For example if you want to download a file from internet you need to send following command to http server. If you want to download a file index.html, then request header would look like


Get index.html HTTP/1.1\r\n

Host: www.myhost.com


You may add more header fields, but these are the least you require to send to http server.

The following are the steps that you may need to follow

1. Connect to HTTP server over port 80[or 8080 normally these ports are used for http server]
2. Send Http request as I proposed above.
3. In reply, Http server would send you Http response which starts as


HTTP/1.1 200 OK\r\n

Location: blalbah

Content Type: text\r\b

Content Length: 500\r\n

\r\n

\r\n

File content starts now!


The response always starts with header which contains important fields like content type and content length. after a double carriage return \r\n\r\n, the actual file data comes that you need to save your output file.

I hope this helps

Munir

#7
Kuto

Kuto

    Learning Programmer

  • Members
  • PipPipPip
  • 49 posts
@sam_coder and @mnirahd thanks alot, yes finally its working, i can download anyfile. i v never tried like that , i always download html, php or asp files with this way, but i thought only i can download webpages :)

Thank you sooo much again.

#8
Kuto

Kuto

    Learning Programmer

  • Members
  • PipPipPip
  • 49 posts

mnirahd said:

Hi,

A quick solution to have a cross plateform working solution is to Use libCurl to download/upload your files over http:

a working code example to download file is


#define CURL_STATICLIB

#include <stdio.h>

#include <curl/curl.h>

#include <curl/types.h>

#include <curl/easy.h>

#include <string>


size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {

    size_t written;

    written = fwrite(ptr, size, nmemb, stream);

    return written;

}


int main(void) {

    CURL *pCurl;

    FILE *fptr;

    CURLcode codes;

    char *url = "http://yourhost/aaa.txt";

    char outfilename[256] = "C:\\downloadedfile.txt";

    pCurl = curl_easy_init();

    if (pCurl) {

        fptr = fopen(outfilename,"wb");

        curl_easy_setopt(pCurl, CURLOPT_URL, url);

        curl_easy_setopt(pCurl,, CURLOPT_WRITEFUNCTION, write_data);

        curl_easy_setopt(pCurl,, CURLOPT_WRITEDATA, fptr);

        res = curl_easy_perform(pCurl);

        curl_easy_cleanup(pCurl);

        fclose(fptr);

    }

    return 0;

}



I hope that helps! Let me know if you thinking to use LibCurl: i can provide you lib/dll for this!

Munir

Hi munir, first of all thanks to mention about libcurl. Long time ago, i have tried to write an email sender but i couldnt be succesfull. Because of ssl connection. But when i research about libcurl, i v seen examples for sending email with ssl connection, and finally i wrote an email sender.

But my problem is that, i dont want my program has dependency of 4 dll files. i v tried long time to link my program static, but i failed. I have static library for mingw and visual C++ but, even i try everything , i never could link it static.

If you need to see, i can write my code also...

#9
mnirahd

mnirahd

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 330 posts
Hi,

in order to use static libcurl: you have to define macro

#define STATIC_LIBCURL


this would let you use static version of libcurl.

what're the other libraries you want to link statically?

Yes please send us the code

Thanks
Munir

#10
brownhead

brownhead

    Programmer

  • Members
  • PipPipPipPip
  • 173 posts
I wrote a function to do this awhile back. It uses INet. You won't be able to do what your trying to do without accessing a DLL because the operating system is going to be who has the final say on all internet related magic, and you'll need to access the operating systems API somehow..
I wrote it in C, so it is a little bit painful to read. It also simply sticks the file into memory and give you a pointer to it... Hopefully it helps, and if you do end up using it and you improve it, please share your improvements :).

C | /** * Retrieves the contents of a file from a re - Brownhead - Template Issues

Note: You'll need to include wininet.h and string.h.

#11
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,254 posts
  • Location:C:\Countries\US

mnirahd said:

Hi,

In order to use winsock function and download a file from internet: you must be familiar with Http protocol. In order to download a file you must prepare a valid http request header: For example if you want to download a file from internet you need to send following command to http server. If you want to download a file index.html, then request header would look like


Get index.html HTTP/1.1\r\n

Host: www.myhost.com


You may add more header fields, but these are the least you require to send to http server.

The following are the steps that you may need to follow

1. Connect to HTTP server over port 80[or 8080 normally these ports are used for http server]
2. Send Http request as I proposed above.
3. In reply, Http server would send you Http response which starts as


HTTP/1.1 200 OK\r\n

Location: blalbah

Content Type: text\r\b

Content Length: 500\r\n

\r\n

\r\n

File content starts now!


The response always starts with header which contains important fields like content type and content length. after a double carriage return \r\n\r\n, the actual file data comes that you need to save your output file.

I hope this helps

Munir


I just thought shouldn't it be "Content-Length" instead of "Content Length" or does it not matter?

#12
mnirahd

mnirahd

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 330 posts
Hi,


yes, it should have been Content-Length: My mistake!!

Munir




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users