I'm still seeing this in your code
and I really think I shouldn't be.Code:char *REMOTE_URL = "http://iss.netii.net/projects/message/";
I'm still seeing this in your code
and I really think I shouldn't be.Code:char *REMOTE_URL = "http://iss.netii.net/projects/message/";
You're trying to do an HTTP PUT to an Apache server. I don't believe that Apache supports PUT out of the box, hence the "Method not allowed" error. You need to properly configure Apache to support PUT. Here's one link to that end.
No this is the new code.
See, the code seems fine, but it's my server permissions that are messed up.Code:#include <stdio.h> #include <string.h> #include <curl/curl.h> #include <curl/types.h> #include <curl/easy.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #ifdef WIN32 #include <io.h> #else #include <unistd.h> #endif /* * This example shows an FTP upload, with a rename of the file just after * a successful upload. * * Example based on source code provided by Erick Nuwendam. Thanks! */ #define LOCAL_FILE "feed.txt" #define RENAME_FILE_TO "feed.zip" #define UPLOAD_FILE_AS "feed.txt" /* NOTE: if you want this example to work on Windows with libcurl as a DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION. Failing to do so will give you a crash since a DLL may not use the variable's memory when passed in to it from an app like this. */ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) { /* in real-world cases, this would probably get this data differently as this fread() stuff is exactly what the library already would do by default internally */ size_t retcode = fread(ptr, size, nmemb, stream); printf("*** We read %d bytes from file\n", retcode); return retcode; } int main(void) { CURL *curl; CURLcode res; FILE *hd_src; struct stat file_info; curl_off_t fsize; char *REMOTE_URL = "ftp://iss.netii.net/projects/message/"; struct curl_slist *headerlist=NULL; static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS; static const char buf_2 [] = "RNTO " RENAME_FILE_TO; /* get the file size of the local file */ if(stat(LOCAL_FILE, &file_info)) { printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno)); return 1; } fsize = (curl_off_t)file_info.st_size; printf("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize); /* get a FILE * of the same file */ hd_src = fopen(LOCAL_FILE, "rb"); /* In windows, this will init the winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ curl = curl_easy_init(); if(curl) { /* build a list of commands to pass to libcurl */ headerlist = curl_slist_append(headerlist, buf_1); headerlist = curl_slist_append(headerlist, buf_2); /* we want to use our own read function */ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* specify target */ curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL); /* pass in that last of FTP commands to run after the transfer */ curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist); /* now specify which file to upload */ curl_easy_setopt(curl, CURLOPT_READDATA, hd_src); /* specify username and password for ftp */ curl_easy_setopt(curl, CURLOPT_USERNAME, "username"); curl_easy_setopt(curl, CURLOPT_PASSWORD, "password"); /* Set the size of the file to upload (optional). If you give a *_LARGE option you MUST make sure that the type of the passed-in argument is a curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must make sure that to pass in a type 'long' argument. */ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); /* Now run off and do what you've been told! */ res = curl_easy_perform(curl); /* clean up the FTP commands list */ curl_slist_free_all (headerlist); /* always cleanup */ curl_easy_cleanup(curl); } fclose(hd_src); /* close the local file */ getchar(); curl_global_cleanup(); return 0; }
In regards to the above post, this is just a free server I'm using for testing purposes. I don't have full access to the Apache server, as it's from 000webhost. (but I do have .htaccess support)
How can I get around this problem?
Last edited by binks; 07-21-2011 at 12:26 PM.
To be frank here, you aren't doing the greatest job of "earning" our help. You really don't seem to be making an effort to understand FTP or curl. You're just scoop-and-pooping the curl example, and when it doesn't work, you post here and say "please fix", without giving us any details of how you're supposed to connect. There is nothing wrong with your C code, or your overall use of libcurl. Your problem is that you don't understand FTP or how the server is set up. To figure out how it is set up, you have to check with whoever hosts your website (000webhost?). They should have some documentation on how to upload files for your free website. That should tell you the connection details for FTP (and HTTP if it's supported). At the very least, they should have a web form or email address for contacting support. Their site/support team should get you going on what specific curl options you need to set.
Considering this is just a free server you're using for testing, what works here might not work on your production server, so you definitely need to understand how to use HTTP and/or FTP thoroughly so you can easily convert your code to work with your production server, come time.
As for help with your specific, current problem, why don't you try turning verbose output back on, and try Googling whatever error message curl spits out when it tells you you failed. I'd bet good money you're not the first person to ever come across that error, and that your question has been asked and answered a number of times in a number of different forums, and recorded for posterity. An incredibly important part of being a programming is learning how to research your problem and look through existing documentation, tutorials, forums, etc and apply that knowledge to your own solution.
Please, don't post back here until you have the connection info for uploading files to your web site and have made some effort to figure this out on your own (beyond copying a tutorial).
I got it working, and I found out thanks to your advice of enabling verbose tracing! I love you for that!!
Here is the final code, and output, for anyone else facing this issue.
And the outputCode:#include <stdio.h> #include <string.h> #include <curl/curl.h> #include <curl/types.h> #include <curl/easy.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #ifdef WIN32 #include <io.h> #else #include <unistd.h> #endif /* * This example shows an FTP upload, with a rename of the file just after * a successful upload. * * Example based on source code provided by Erick Nuwendam. Thanks! */ #define LOCAL_FILE "feed.txt" #define RENAME_FILE_TO "feed.zip" #define UPLOAD_FILE_AS "feed.txt" /* NOTE: if you want this example to work on Windows with libcurl as a DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION. Failing to do so will give you a crash since a DLL may not use the variable's memory when passed in to it from an app like this. */ static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) { /* in real-world cases, this would probably get this data differently as this fread() stuff is exactly what the library already would do by default internally */ size_t retcode = fread(ptr, size, nmemb, stream); printf("*** We read %d bytes from file\n", retcode); return retcode; } int main(void) { CURL *curl; CURLcode res; FILE *hd_src; struct stat file_info; double speed_upload, total_time; curl_off_t fsize; // I had to add public_html as a folder, because it said there was no projects directory. As well as add the filename to the final URL below char *REMOTE_URL = "ftp://iss.netii.net/public_html/projects/message/feed.zip"; struct curl_slist *headerlist=NULL; static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS; static const char buf_2 [] = "RNTO " RENAME_FILE_TO; /* get the file size of the local file */ if(stat(LOCAL_FILE, &file_info)) { printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno)); return 1; } fsize = (curl_off_t)file_info.st_size; printf("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize); /* get a FILE * of the same file */ hd_src = fopen(LOCAL_FILE, "rb"); /* In windows, this will init the winsock stuff */ curl_global_init(CURL_GLOBAL_ALL); /* get a curl handle */ curl = curl_easy_init(); if(curl) { /* build a list of commands to pass to libcurl */ headerlist = curl_slist_append(headerlist, buf_1); headerlist = curl_slist_append(headerlist, buf_2); /* we want to use our own read function */ curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* specify target */ curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL); /* pass in that last of FTP commands to run after the transfer */ curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist); /* now specify which file to upload */ curl_easy_setopt(curl, CURLOPT_READDATA, hd_src); /* specify username and password for ftp */ curl_easy_setopt(curl, CURLOPT_USERNAME, "username"); curl_easy_setopt(curl, CURLOPT_PASSWORD, "password"); /* Set the size of the file to upload (optional). If you give a *_LARGE option you MUST make sure that the type of the passed-in argument is a curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must make sure that to pass in a type 'long' argument. */ curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)fsize); /* enable verbose for easier tracing */ curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); /* Now run off and do what you've been told! */ res = curl_easy_perform(curl); /* now extract transfer info */ curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload); curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time); printf("Speed: %.3f bytes/sec during %.3f seconds\n", speed_upload, total_time); /* clean up the FTP commands list */ curl_slist_free_all (headerlist); /* always cleanup */ curl_easy_cleanup(curl); } fclose(hd_src); /* close the local file */ getchar(); curl_global_cleanup(); return 0; }
libcurl did the rest, as it found it was passive mode, among other things.
Thank you so much for your help!