20161228_jeffrey - silenceuncrio/diary GitHub Wiki

Index

  • 0930 - review
  • 1005 - 改一隻 /tmp/test.sh
  • 1500 - firmware.tar 大於 20MB - 上傳就失敗了
  • 1555 - 利用 mongoose 在 iweb 寫個 upload file 的 api
  • 1645 - 成功把 2xMB 的 firmware.tar 傳到 m300 的 /tmp/xxx.file
  • 1700 - 把範例 big_upload.c 整到 iweb.c
  • 1800 - 成功上傳 2xMB 的 firmware.tar - firmware.cgi 呼叫 /tmp/test.sh 作事

0930

review

1005

改一隻 /tmp/test.sh

echo "test start..."
echo "test start..." > /tmp/test.log
echo "sleep 5 sec"
echo "sleep 5 sec" >> /tmp/test.log
sleep 5
echo "sleep 6 sec"
echo "sleep 6 sec" >> /tmp/test.log
sleep 6
echo "test finish"
echo "test finish" >> /tmp/test.log

1500

目前的 shell script - /tmp/test.sh

echo "test start..."
echo "test start..." > /tmp/test.log
echo "Extract all files from $1"
echo "Extract all files from $1" >> /tmp/test.log

if tar -xf $1
then
  echo "tar -xf $1 succeeded"
  echo "tar -xf $1 succeeded" >> /tmp/test.log
else
  echo "tar -xf $1 failed"
  echo "tar -xf $1 failed" >> /tmp/test.log
  echo "finished" >> /tmp/test.log
  exit 1
fi

echo "sleep 5 sec"
echo "sleep 5 sec" >> /tmp/test.log
sleep 5

echo "sleep 6 sec"
echo "sleep 6 sec" >> /tmp/test.log
sleep 6
echo "test finished"
echo "test finished" >> /tmp/test.log

目前的 cgi - firmware.c

...
static void _upgrade() {
    char cmd[256];

    sprintf(cmd, "cp %s /tmp/firmware.tar 1>/dev/null 2>&1", jweb.in.files[0]->tmpfile);
    system(cmd);

    sprintf(cmd, "/tmp/test.sh /tmp/firmware.tar 1>/dev/null 2>&1 &");
    system(cmd);

    jweb.out.json.data("tmpfile", json_object_new_string(jweb.in.files[0]->tmpfile));
}

...

int main(void) {
    jweb.cgi.init();

    if        (STRCMP(jweb.in.act, "upgrade")) {
        _upgrade();
    } else if (STRCMP(jweb.in.act, "progress")) {
        _progress();
    } else if (STRCMP(jweb.in.act, "help")) {
        _help();
    } else {
        jweb.http.status(400);
        jweb.out.json.fail("act invalid");
    }
}

這樣的組合可以達到

  • 上傳檔案
  • 隨便上傳檔案會讓 tar 解不開 - exit 1

不過目前掉進一個大坑

我們的 firmware.tar 大於 20MB

光上傳就失敗了

就算 cgi 被叫起來了也會抱怨沒有指定 act

1555

懷疑是 cgi.ccgiReadMultipart() 裡的 cgiReadFile() 有問題

參考 https://github.com/cesanta/mongoose/blob/master/examples/big_upload/big_upload.c

利用 mongoose 這個 embedded web library 在 iweb 寫個 upload file 的 api

1645

範例 big_upload.c 小修一下

static void handle_upload(struct mg_connection *nc, int ev, void *p) {
  struct file_writer_data *data = (struct file_writer_data *) nc->user_data;
  struct mg_http_multipart_part *mp = (struct mg_http_multipart_part *) p;

  switch (ev) {
    case MG_EV_HTTP_PART_BEGIN: {
      if (data == NULL) {
        data = calloc(1, sizeof(struct file_writer_data));

#if 0
        data->fp = tmpfile();
#else
        data->fp = fopen("/tmp/xxx.file", "w+");
#endif

        data->bytes_written = 0;

        if (data->fp == NULL) {
          mg_printf(nc, "%s",
                    "HTTP/1.1 500 Failed to open a file\r\n"
                    "Content-Length: 0\r\n\r\n");
          nc->flags |= MG_F_SEND_AND_CLOSE;
          return;
        }
        nc->user_data = (void *) data;
      }
      break;
    }
    ...
  }
}
...

成功的把我們 2xMB 的 firmware.tar 傳到 m300 的 /tmp/xxx.file

也成功解了開來

好險我們早一步改用 mongoose 這個 embedded web library

不然被綁在 libcgi.so 這一套 cgi library 的話

像上傳我們 m300 這相對公司其他產品來說大上許多的 image 的話 - 2xMB

肯定會被笑話...

1700

把範例 big_upload.c 整到我們 iweb.c

1800

目前的 shell script - /tmp/test.sh

echo "test start..."
echo "test start..." > /tmp/test.log
echo "Extract all files from $1"
echo "Extract all files from $1" >> /tmp/test.log

if tar -C /tmp -xf $1
then
  echo "tar -C /tmp -xf $1 succeeded"
  echo "tar -C /tmp -xf $1 succeeded" >> /tmp/test.log
else
  echo "tar -C /tmp -xf $1 failed"
  echo "tar -C /tmp -xf $1 failed" >> /tmp/test.log
  echo "finished" >> /tmp/test.log
  exit 1
fi

echo "sleep 5 sec"
echo "sleep 5 sec" >> /tmp/test.log
sleep 5

echo "sleep 6 sec"
echo "sleep 6 sec" >> /tmp/test.log
sleep 6
echo "test finished"
echo "test finished" >> /tmp/test.log

目前已經透過 iweb 的 /api/firmwareUpload 成功上傳 2xMB 的 firmware.tar 到 m300 的 /tmp

並透過 cgi-bin/firmware.cgi?act=upgrade 呼叫 /tmp/test.sh 開始作事

然後透過 cgi-bin/firmware.cgi?act=progress 來得知目前的 firmware upgrade 進度