Synology Upload API is not responding. just timeout

30 views Asked by At

My Code is Here.

I want to upload files to synology using nestjs. but it's not running my expected.

synology is not responding until timeout.

Where is the problem in my code?

https://global.download.synology.com/download/Document/Software/DeveloperGuide/Package/FileStation/All/enu/Synology_File_Station_API_Guide.pdf (FormData is not 'form-data')

  // Service
  import { HttpService } from '@nestjs/axios';

  constructor(private readonly http: HttpService) {}

  async uploadFile(files: File[], file_path: string) {
    try {
      const formData = new FormData();
      for (const file of files) {
        formData.append('file', file);
      }

      const data = await firstValueFrom(
        this.http
          .post(process.env.SYNOLOGY_URL, formData, {
            params: {
              api: 'SYNO.FileStation.Upload',
              version: 2,
              method: 'upload',
              _sid: this.sid,
              path: file_path,
              create_parents: false,
              overwrite: false,
            },
          })
          .pipe(map((response) => response.data)),
      );
    } catch (error) {
      console.error(JSON.stringify(error, null, 2));
    }
  }

timeout response

{
  "message": "timeout of 10000ms exceeded",
  "name": "AxiosError",
  "stack": "AxiosError: timeout of 10000ms exceeded\n    at RedirectableRequest.handleRequestTimeout (/usr/projects/backend/init_nestjs/node_modules/axios/lib/adapters/http.js:647:16)\n    at RedirectableRequest.emit (node:events:518:28)\n    at Timeout.<anonymous> (/usr/projects/backend/init_nestjs/node_modules/follow-redirects/index.js:210:12)\n    at listOnTimeout (node:internal/timers:573:17)\n    at processTimers (node:internal/timers:514:7)\n    at Axios.request (/usr/projects/backend/init_nestjs/node_modules/axios/lib/core/Axios.js:45:41)",
  "config": {
    "transitional": {
      "silentJSONParsing": true,
      "forcedJSONParsing": true,
      "clarifyTimeoutError": false
    },
    "adapter": [
      "xhr",
      "http"
    ],
    "transformRequest": [
      null
    ],
    "transformResponse": [
      null
    ],
    "timeout": 10000,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1,
    "maxBodyLength": -1,
    "env": {},
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "Content-Type": "multipart/form-data; boundary=axios-1.6.8-boundary-KyPk5XLtcOCa_vHTRUxIf-PRY",
      "User-Agent": "axios/1.6.8",
      "Content-Length": "263074",
      "Accept-Encoding": "gzip, compress, deflate, br"
    },
    "maxRedirects": 5,
    "params": {
      "api": "SYNO.FileStation.Upload",
      "version": 2,
      "method": "upload",
      "_sid": "SYNOLOGY_SID"
      "path": "/docker",
      "create_parents": false,
      "overwrite": false
    },
    "method": "post",
    "url": "SYNOLOGY_URL/webapi/entry.cgi",
    "data": {}
  },
  "code": "ECONNABORTED",
  "status": null
}

using import * as FormData from 'form-data' instead of basic FormData. because using formData.getHeaders().

but i show error 'source.on is not a function' when formData.append('file', file)

2

There are 2 answers

1
Marek Kapusta-Ognicki On

--> post(process.env.SYNOLOGY_URL, ...)

I would definitely check first if SYNOLOGY_URL is in the environment

--> env: {}

Protip: if you're using .env file, its contents must be first loaded into the environment. For example, by ConfigService (which you're not using here), dotenv or anything like that. That's why skipping NestJS native configuration logic backfires in 99% cases.

Or, after another look:

"url": "SYNOLOGY_URL/webapi/entry.cgi",

Is that a correct URL?

On a third look, did you set the correct request header?

On a fourth look, grab nestjs-http-promise - you won't need to struggle with rxjs.

0
 souldiary On

I got it.

The solution is to put params data into formdata.

const formData = new FormData();
  formData.append('api', 'SYNO.FileStation.Upload');
  formData.append('version', '2');
  formData.append('method', 'upload');
  formData.append('path', file_path);
  formData.append('create_parent', 'false');
  formData.append('overwrite', 'false');
  files.forEach(async (file: Express.Multer.File) => {
    const bufData = Buffer.from(file.buffer);
    const blobData = new Blob([bufData], {
      type: file.mimetype,
    });
    formData.append('file', blobData, file.originalname);
  });

  const data = await firstValueFrom(
    this.http
      .post(process.env.SYNOLOGY_URL, formData, {
        params: {
          _sid: this.sid,
        },
      })
      .pipe(map((response) => response.data)),
  );