mercredi 11 décembre 2019

Uploading a file to a REST server using libcurl

I have a test http server in python that is waiting for a POST. The code is below.

File - app.py

from flask import Flask

UPLOAD_FOLDER = '/home/karthik/upload'

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 * 1024 * 1024

File - main.py

import os
import urllib.request
from app import app
from flask import Flask, request, render_template, redirect, jsonify
from werkzeug.utils import secure_filename

ALLOWED_EXTENSIONS = set(['out', 'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route("/")
def fileFrontPage():
    return render_template('fileform.html')

@app.route('/file-upload', methods=['POST'])
def upload_file():
    # check if the post request has the file part
    if 'file' not in request.files:
        resp = jsonify({'message' : 'No file part in the request'})
        resp.status_code = 400
        return resp
    file = request.files['file']
    if file.filename == '':
        resp = jsonify({'message' : 'No file selected for uploading'})
        resp.status_code = 400
        return resp
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        resp = jsonify({'message' : 'File successfully uploaded'})
        resp.status_code = 201
        return resp
    else:
        resp = jsonify({'message' : 'Allowed file types are txt, pdf, png, jpg, jpeg, gif'})
        resp.status_code = 400
        return resp

if __name__ == "__main__":
    app.run(debug=True)

I have a C++ function that POSTS the contents of a file onto the server. (shown below)

int upload(const std::string &filename, const std::string &url) {
    curl_off_t speed_upload;
    struct WriteThis wt;
    CURLcode res;
    struct curl_slist *chunk = NULL;

    std::vector<uint8_t> vec = readFile(filename.c_str());
    char* data = new char[vec.size()];
    std::cout << "vector size : " << vec.size() << std::endl;

    std::copy(vec.begin(),vec.end(), data);
    wt.readptr = data;
    wt.sizeleft = strlen(data);

    std::cout << "sizeleft : " << wt.sizeleft << std::endl;

    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_POST, 1L);
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
    curl_easy_setopt(curl, CURLOPT_READDATA, &wt);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

    res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        std::cout <<  "curl_easy_perform() failed: " << curl_easy_strerror(res);
    } else {
        curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
        m_logger->infof("Average Upload speed: %.7f  megabytes/sec",
                        (speed_upload/1000000));

    }
    return 0;
}

The output is shown below.

URL : http://127.0.0.1:5000/file-uploadFilename : /home/downloadfile.out
vector size : 663876582
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
> POST /file-upload HTTP/1.1
Host: 127.0.0.1:5000
Accept: */*
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

< HTTP/1.1 100 Continue
* HTTP 1.0, assume close after body
< HTTP/1.0 400 BAD REQUEST
< Content-Type: application/json
< Content-Length: 47
< Server: Werkzeug/0.16.0 Python/3.5.2
< Date: Thu, 12 Dec 2019 09:33:20 GMT
< 
* Closing connection 0
{
  "message": "No file part in the request"
}

Aucun commentaire:

Enregistrer un commentaire