Skip to content

Instantly share code, notes, and snippets.

@pandanote-info
Created March 25, 2022 08:18
Show Gist options
  • Save pandanote-info/3ee5a0cae4bf1e3af18106c567368cd5 to your computer and use it in GitHub Desktop.
Save pandanote-info/3ee5a0cae4bf1e3af18106c567368cd5 to your computer and use it in GitHub Desktop.
POSTメソッドで受け取ったbodyからバイナリデータを取り出し、IPFSノードにアップロードするNode.jsのプログラムのプログラム片。
// See https://pandanote.info/?p=8723 for details.
import * as fs from 'fs';
import axios from 'axios';
import FormData from 'form-data';
function getBoundary(header) {
var tmpct = header['content-type'].split(/;/);
var boundary = tmpct.filter(function(e) {
return e.trim().startsWith("boundary=");
});
if (boundary.length > 0) {
return boundary[0].trim().replace("boundary=","");
}
return null;
}
function uploadToIpfs(v, req, res) {
let buffer = [];
req.setEncoding('binary');
let length = 0;
req.on('data', function(chunk) {
length += chunk.length;
buffer += chunk;
});
req.on('end', async function() {
console.log(req.headers);
// console.log(buffer.length);
var boundary = getBoundary(req.headers);
if (boundary != null) {
var partlist = [];
var attrlist = {};
// 0: start,
// 1: in-part(text),
// 2: in-part(pre-content),
// 3: in-part(binary)
var mode = 0;
var linebuf = [];
var i = 0;
while (i < buffer.length) {
const cp = i > 0?buffer.charCodeAt(i-1) & 0xff: 0;
const c = buffer.charCodeAt(i) & 0xff;
if (mode != 3) {
if (cp == 0x0d && c == 0x0a) {
var lb = linebuf.trim();
linebuf = [];
if (lb == "--"+boundary) {
mode = 1;
} else if (mode == 1) {
if (lb.startsWith("Content-Disposition")) {
var attrs = lb.replace(/^Content-Disposition:\s+/,"").split(/;/);
attrs.forEach(attr => {
var at = attr.trim().split(/=/);
if (at.length < 2) {
attrlist[at[0]] = "";
} else {
attrlist[at[0]] = at[1].replace(/^\"([^\"]+)\"/,"$1");
}
});
//console.log(attrlist);
} else if (lb.startsWith("Content-Type")) {
attrlist["Content-Type"] = lb.replace(/^Content-Type:\s+/,"");
partlist.push(attrlist);
attrlist = {};
mode = 2;
//console.log(partlist);
}
} else if (mode == 2) {
mode = 3;
var ccp = 0;
var cc = 0;
do {
i+=2;
ccp = buffer.length > i-1? buffer.charCodeAt(i-1) & 0xff: 0;
cc = buffer.length > i? buffer.charCodeAt(i) & 0xff: 0;
//console.log(ccp+":"+cc);
} while(ccp == 0x0d && cc == 0x0a);
i-=2;
}
} else {
linebuf += buffer[i];
}
} else {
var j = buffer.indexOf("--"+boundary,i);
if (j > i) {
partlist[partlist.length-1]["content"] = buffer.slice(i,j-2);
mode = 0;
linebuf = [];
//console.log(partlist);
i = j-1;
//console.log(partlist[partlist.length-1]["content"].length);
}
}
i++;
}
let buf = Buffer.from(partlist[partlist.length-1]["content"],'binary');
var ipfsform = new FormData();
ipfsform.append("image",buf);
axios.post('http://localhost:5001/api/v0/add', ipfsform,
{ headers: ipfsform.getHeaders() })
.then(response => {
res.writeHead(200, {"Content-Type": "text/plain"});
res.write(JSON.stringify(response.data));
res.end();
})
.catch(error => {
console.log(error);
res.writeHead(500, {"Content-Type": "text/plain"});
res.write(error);
res.end();
});
} else {
// console.log(error);
res.writeHead(400, {"Content-Type": 'text/html; charset=utf-8'});
res.write(fs.readFileSync("static/400.html"));
res.end();
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment