Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RE: Nativescript plugin background-http produces issue "error during upload" #770

Closed
samliaw opened this issue Apr 25, 2017 · 2 comments
Closed

Comments

@samliaw
Copy link

samliaw commented Apr 25, 2017

Hi, I am testing nativescript-background-http to test upload a picture file to server.

I test using physical mobile device. Below is the coding file
==================================start of a.component.ts================================

import { Component } from '@angular/core';
import * as bghttp from "nativescript-background-http";
import * as fs from "file-system";

@Component({
    moduleId: module.id,
    template: "<Button text='Upload File' (tap)='uploadFile()'></Button>"
})
export class aComponent {
    public session = bghttp.session("image-upload");

    uploadFile() {
        const filepath: string = "/data/user/0/org.nativescript.Groceries/cache/img_by_sj_1493113215112.jpg";
        const filename: string = "img_by_sj_1493113215112.jpg";

         
        let fileExist = fs.File.exists(filepath);
        // confirm file exists.
        console.log("file exist? ", fileExist);
        let request = {
            url: "http://it-enable.net:9191/file",
            method: "post",
            headers: {
                "Content-Type": "application/octet-stream",
                "File-name": filename
            },
            description: "{ 'uploading': '" + filename + "' }"
        }

        let task = this.session.uploadFile(filepath, request);
        task.on("progress", this.logEvent);
        task.on("error", this.logEvent);
        task.on("complete", this.logEvent);

    }
    logEvent(e) {
        console.dump(e);
    }
}

==================================end of a.component.ts================================

==================================start of package.json================================

{
  "name": "typescript anuglar redux",
  "version": "0.0.1",
  "description": "NativeScript Application",
  "license": "SEE LICENSE IN <your-license-filename>",
  "readme": "NativeScript Application",
  "repository": "<fill-your-repository-here>",
  "nativescript": {
    "id": "org.nativescript.Groceries",
    "tns-android": {
      "version": "2.5.0"
    }
  },
  "dependencies": {
    "@angular/common": "2.4.3",
    "@angular/compiler": "2.4.3",
    "@angular/core": "2.4.3",
    "@angular/forms": "2.4.3",
    "@angular/http": "2.4.3",
    "@angular/platform-browser": "2.4.3",
    "@angular/platform-browser-dynamic": "2.4.3",
    "@angular/router": "3.4.3",
    "@ngrx/core": "^1.2.0",
    "@ngrx/effects": "^2.0.2",
    "@ngrx/store": "^2.2.1",
    "email-validator": "^1.0.7",
    "file-system": "^2.2.2",
    "nativescript-angular": "1.4.0",
    "nativescript-background-http": "^2.5.1",
    "nativescript-camera": "0.0.8",
    "nativescript-drawingpad": "^1.1.2",
    "nativescript-social-share": "^1.3.2",
    "nativescript-telerik-ui-pro": "file:F:\\NativeScript\\Packages\\nativescript-ui-pro.tgz",
    "nativescript-theme-core": "~1.0.2",
    "ramda": "^0.23.0",
    "reflect-metadata": "~0.1.8",
    "rxjs": "~5.0.1",
    "tns-core-modules": "2.5.0"
  },
  "devDependencies": {
    "babel-traverse": "6.4.5",
    "babel-types": "6.4.5",
    "babylon": "6.4.5",
    "eslint": "^3.19.0",
    "lazy": "1.0.11",
    "nativescript-dev-android-snapshot": "^0.*.*",
    "nativescript-dev-typescript": "^0.3.5",
    "typescript": "~2.1.0",
    "zone.js": "~0.7.2"
  }
}

==================================end of package.json================================

I am using the node.js restify to accept the file. I have tested using Postman and it works file. The code of the restify is as below
==================================start of restify index.js================================

var restify = require('restify');
var fs = require('fs');
var os = require('os');
var server = restify.createServer({
    name: 'software-manufacture-backend-file',
    version: '0.1.0'
});
var Throttle = require("stream-throttle").Throttle;
var outDir = "/mnt/diskc/p/restify-file/uploads/";
server.use(restify.acceptParser(server.acceptable));
server.use(restify.CORS());
server.use(restify.queryParser());
server.use(restify.gzipResponse());
server.use(function (req, res, next) {
    console.log('it reach the restify-file api without body parser');
    return next();
});
server.get('/test', function (req, res, next) {
    res.send(200, 'SUCCESS');
    res.end;
    return next();
});
server.post('/file', function (req, res, next) {
    console.log(req.params);
    var fileName = req.headers["file-name"];
    console.log("req.headers are", req.headers);
    var logger = console;
    logger.log(req.method + "Request! Content-Length: " + req.headers["content-length"] + ", file-name: " + fileName);
    logger.dir(req.headers);
    var out = outDir + "upload-" + new Date().getTime() + "-" + fileName;
    logger.log("Output in: " + out);
    var total = req.headers["content-length"];
    var current = 0;
    var shouldFail = req.headers["should-fail"];
    req.pipe(new Throttle({ rate: 1024 * 2048 })).pipe(fs.createWriteStream(out, { flags: 'w', encoding: null, fd: null, mode: 0666 }));
    req.on('data', function (chunk) {
        current += chunk.length;
        if (shouldFail && (current / total > 0.25)) {
            logger.log("Error ");
            var body = "Denied!";
            res.send(408, "Die!", { "Content-Type": "text/plain", "Content-Length": body.length, "Connection": "close" });
            res.end();
            shouldFail = false;
            logger.log("Terminated with error: [" + out + "]: " + current + " / " + total + "  " +
                Math.floor(100 * current / total) + "%");
        }
        else {
            logger.log("Data [" + out + "]: " + current + " / " + total + "  " + Math.floor(100 * current / total) + "%");
        }
    });
    req.on('end', function () {
        logger.log("Done (" + out + ")");
        var body = "Upload complete!";
        res.send(200, "Done!", { "Content-Type": "text/plain", "Content-Length": body.length });
        res.end();
    });
    req.on('error', function (e) {
        logger.log('it reach the file received error!');
        logger.log(e);
    });
});
process.on('uncaughtException', function (err) {
    console.log('uncaught Exception is ', err);
});
server.listen(9191, function () {
    console.log('%s listening at %s', server.name, server.url);
});

==================================end of restify index================================

==================================start of restify packson.json================================

{
  "name": "restify-file",
  "version": "0.0.1",
  "description": "It only accepts files",
  "main": "index.js",
  "author": "Sam Liaw <samliaw@it-enable.net>",
  "license": "MIT",
  "dependencies": {
    "ramda": "^0.23.0",
    "restify": "^4.3.0",
    "stream-throttle": "^0.1.3"
  }
}

==================================endof restify packson.json================================

When I use the Postman, I provide the following attirbutes
Method: Post
URL: http://it-enable.net:9191/file
Header: {"Content-Type":"application/octet-stream"}
Attached a picture file.

If the file is uploaded successfully, I can see the response of "Done!".

When I run the project in physical mobile device, I hit the error "error during upload." When I look at backend restify, I find that the nativescript-background-http hits error before it sends the file to backend restify. This is because the backend restify doesn't inidicate it has receives any file.

I do test this whole afternoon but to no vail. I copy the source code that people have claim successful executing but it doesn't work for me. There is no detail error code so I am not able to figure what is wrong.

Any suggestion or method is welcomed.

@NickIliev
Copy link

This issue was moved to NativeScript/nativescript-background-http#61

@samliaw
Copy link
Author

samliaw commented Apr 26, 2017

Hi,

I spend some more time to debug and finally confirm what cause the issue. Please look at the code in the component. I simply change the lowercase "post" to all uppercase "POST" and it works perfectly.

hopefully this will help other people who face similar issue like me.

    let request = {
        url: "http://it-enable.net:9191/file",
        method: "post", //<----- change post to POST solve the issue
        headers: {
            "Content-Type": "application/octet-stream",
            "File-name": filename
        },
        description: "{ 'uploading': '" + filename + "' }"
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants