149 lines
4.3 KiB
C++
149 lines
4.3 KiB
C++
// Copyright (c) 2009, Amar Takhar <verm@aegisub.org>
|
|
//
|
|
// Permission to use, copy, modify, and distribute this software for any
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
// copyright notice and this permission notice appear in all copies.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
//
|
|
// $Id$
|
|
|
|
/// @file upload.cpp
|
|
/// @brief Handle uploading of data.
|
|
/// @ingroup base io
|
|
|
|
#ifndef R_PRECOMP
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <wx/file.h>
|
|
#endif
|
|
|
|
#include "upload.h"
|
|
|
|
/// @brief Constructor.
|
|
Upload::Upload(Progress *prog) {
|
|
/// XXX: error checking.
|
|
progress = prog;
|
|
handle = curl_easy_init();
|
|
// curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L);
|
|
curl_easy_setopt(handle, CURLOPT_USERAGENT, "Reporter v1.0");
|
|
curl_easy_setopt(handle, CURLOPT_READFUNCTION, CBRead);
|
|
curl_easy_setopt(handle, CURLOPT_PROGRESSFUNCTION, CBProgress);
|
|
curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 0L);
|
|
curl_easy_setopt(handle, CURLOPT_PROGRESSDATA, progress);
|
|
}
|
|
|
|
|
|
/// @brief Destructor.
|
|
Upload::~Upload() {
|
|
curl_free(handle);
|
|
}
|
|
|
|
|
|
/// @brief Submit a JSON report.
|
|
/// @param report filename of the report.
|
|
void Upload::Report(std::string report) {
|
|
wxFile file(report, wxFile::read);
|
|
SendFile("http://reporter.darkbeer.org/PUT/", file);
|
|
}
|
|
|
|
|
|
/// @brief Progress callback.
|
|
/// @param p pointer to progress info.
|
|
/// @param dlt download size.
|
|
/// @param dln downloaded.
|
|
/// @param ult upload size.
|
|
/// @param uln uploaded.
|
|
int Upload::CBProgress(void *p, double dlt, double dln, double ult, double uln) {
|
|
|
|
if (uln > 0) {
|
|
Progress *progress = (Progress*) p;
|
|
// Update returns false if the user has hit abort.
|
|
if (!progress->Update(floor(ult / uln + 0.5) * 100))
|
|
// Returning non-zero will cause curl to abort the transfer.
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/// @brief Callback to read data from a FD.
|
|
/// @param p buffer to fill.
|
|
/// @param size byte length.
|
|
/// @param nmemb object size.
|
|
/// @param filep FP to read from.
|
|
size_t Upload::CBRead(char *p, size_t size, size_t nmemb, void *filep) {
|
|
// This is on purpose to wx doesn't close the fp, curl does that for us.
|
|
wxFile *file = new wxFile((uintptr_t)filep);
|
|
|
|
if (file->Eof())
|
|
return 0;
|
|
|
|
int ret = file->Read(p, file->Length());
|
|
if (ret == wxInvalidOffset)
|
|
return CURL_READFUNC_ABORT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/// @brief Send a file to the server
|
|
/// @param file file to send.
|
|
/// @return 1/0 for success/failure.
|
|
bool Upload::SendFile(const char *url, wxFile &file) {
|
|
progress->Update(0, _("Connecting..."));
|
|
curl_easy_setopt(handle, CURLOPT_URL, url);
|
|
Error(curl_easy_perform(handle));
|
|
|
|
curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L);
|
|
curl_easy_setopt(handle, CURLOPT_PUT, 1L);
|
|
curl_easy_setopt(handle, CURLOPT_READDATA, file.fd());
|
|
curl_easy_setopt(handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file.Length());
|
|
CURLcode res = curl_easy_perform(handle);
|
|
Error(res);
|
|
|
|
curl_easy_setopt(handle, CURLOPT_HTTPGET, 1L); // Reset to HTTP GET
|
|
curl_easy_cleanup(handle);
|
|
if (res == CURLE_OK)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/// @brief Handle error codes
|
|
/// @param error CURLcode.
|
|
void Upload::Error(CURLcode error) {
|
|
switch (error) {
|
|
case CURLE_OK:
|
|
progress->Update(0, _("Sending data..."));
|
|
break;
|
|
case CURLE_COULDNT_RESOLVE_HOST:
|
|
progress->Update(0, _("Couldn't resolve host."));
|
|
break;
|
|
case CURLE_COULDNT_CONNECT:
|
|
progress->Update(0, _("Couldn't connect to server."));
|
|
break;
|
|
|
|
case CURLE_SEND_ERROR: // socket error
|
|
case CURLE_RECV_ERROR: // socket error
|
|
progress->Update(0, _("Connection error."));
|
|
break;
|
|
case CURLE_GOT_NOTHING: // no response from server
|
|
case CURLE_HTTP_RETURNED_ERROR: // HTTP error >= 400
|
|
progress->Update(0, _("Server error."));
|
|
break;
|
|
case CURLE_OPERATION_TIMEDOUT:
|
|
progress->Update(0, _("Operation timeout."));
|
|
break;
|
|
default:
|
|
progress->Update(0, wxString::Format("Transfer error. (%d)\n", error));
|
|
}
|
|
}
|