Related
I am attempting to display an Axis camera live stream in my Next.js front-end after making a request to the Axis API in my custom Node.js server. After making this request
const response = await client.fetch(`http://${ip}/axis-cgi/mjpg/video.cgi?resolution=${resolution}&fps=${fps}&compression=${compression}`, {
method: 'GET',
headers: {
'Content-Type': 'multipart/x-mixed-replace; boundary=--myboundary',
},
});
I get a response with the status code of 200 and the following in the response body:
PassThrough {
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: [Object], tail: [Object], length: 1 },
length: 65351,
pipes: [],
flowing: null,
ended: false,
endEmitted: false,
reading: false,
constructed: true,
sync: false,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
destroyed: false,
errored: null,
closed: false,
closeEmitted: false,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
dataEmitted: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: null
},
_events: [Object: null prototype] {
prefinish: [Function: prefinish],
unpipe: [Function: onunpipe],
error: [ [Function: onerror], [Function (anonymous)] ],
close: [Function: bound onceWrapper] { listener: [Function: onclose] },
finish: [Function: bound onceWrapper] { listener: [Function: onfinish] },
drain: [Function: pipeOnDrainFunctionResult]
},
_eventsCount: 6,
_maxListeners: undefined,
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: true,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 65351,
writing: true,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: [Function: nop],
writelen: 65351,
afterWriteTickInfo: null,
buffered: [],
bufferedIndex: 0,
allBuffers: true,
allNoop: true,
pendingcb: 1,
constructed: true,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
errored: null,
closed: false,
closeEmitted: false,
[Symbol(kOnFinished)]: []
},
allowHalfOpen: true,
[Symbol(kCapture)]: false,
[Symbol(kCallback)]: [Function: bound onwrite]
}
My question is how do you use this data to display the MJPEG on the front-end? Originally, I was passing the URL to an img tag, but this approach does not work in production as the URL is not secure.
OK. I've never done it this way but after a quick googling around I think it's possible to do what you want. So for next.js you can do the following:
WARNING: Untested code
Create an API endpoint for your MJPEG stream.
From the answer to this question (multipart/mixed response using NodeJS) it looks like in the handler you can pipe the fetch response to the res object (assuming that your client.fetch function implements the fetch API).
function handler(req, res) {
const response = await client.fetch(url, options);
response.body.pipeTo(res);
}
On the client side just set the src property of an img tag to the URL of your API endpoint. You can protect the API endpoint with session cookies or a session hash in the URL but using Authorization header won't work because the img tag cannot set custom headers in its request.
I am trying to upload multiple files from sailsjs 1.2.4
Here is my action :
module.exports = {
friendlyName: 'Post',
description: 'Post something.',
files: ['mediaFiles'],
inputs: {
text : {
required: true,
type: 'string',
},
mediaFiles : {
description : "Media files",
example: '===',
required : false
}
},
exits: {
},
fn: async function (inputs) {
inputs.mediaFiles._files.forEach(file=>{
console.log(file)
})
})
}
}
I am getting below result in as file object :
{ stream:
PassThrough {
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: [Object], tail: [Object], length: 2 },
length: 43093,
pipes: null,
pipesCount: 0,
flowing: null,
ended: true,
endEmitted: false,
reading: false,
sync: false,
needReadable: false,
emittedReadable: true,
readableListening: false,
resumeScheduled: false,
emitClose: true,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
{ prefinish: [Function: prefinish],
drain: [Function],
end: [Function],
error: [Array] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: true,
ended: true,
finished: true,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: true,
errorEmitted: false,
emitClose: true,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: false,
allowHalfOpen: true,
_transformState:
{ afterTransform: [Function: bound afterTransform],
needTransform: false,
transforming: false,
writecb: null,
writechunk: null,
writeencoding: 'buffer' },
headers:
{ 'content-disposition':
'form-data; name="mediaFiles"; filename="bwDzrPkA_400x400.jpg"',
'content-type': 'image/jpeg' },
name: 'mediaFiles',
filename: 'bwDzrPkA_400x400.jpg',
byteOffset: 378,
byteCount: 43093,
field: 'mediaFiles' },
status: 'bufferingOrWriting' }
My question is how can I write this file stream to some path like /public/media/xyz.png . I used to with sails normal file upload where I can use this.req.file("name").upload() .. but not in action 2 . I checked other answers but they are uploading to s3 not writing on same server .
You could use a dependency sails-hook-uploads, for that you are able to define the dirpath in your settings:
https://github.com/sailshq/sails-hook-uploads/blob/master/index.js#L31
module.exports.upload = {
dirpath: '.tmp/public', // recommended .tmp/uploads
adapter: require('skipper-disk'), // Default
}
I highly recommend not using the public folder because it's the compiled assets destination, so you'll probably lose these files.
As an alternative, you might use a controller to upload the file as showing below:
https://github.com/mikermcneil/ration/blob/master/api/controllers/things/upload-thing.js#L54
After that, send it to the user:
https://github.com/mikermcneil/ration/blob/master/api/controllers/things/download-photo.js#L50
I want to read a file line by line and based on the data in each line i have to categorise the data.
var rd = readline.createInterface({
input: fs.createReadStream('/home/user/Desktop/text.txt'),
output: process.stdout,
console: false
});
When this line is executed the file is read and printed in the terminal.
But when I try to read the file line by line using readline I am getting error.
rd.on('line', (input) => {
console.log(input);
});
I am getting the following error.
`Interface {
_sawReturnAt: 0,
isCompletionEnabled: true,
_sawKeyPress: false,
_previousKey:
{ sequence: '\n',
name: 'enter',
ctrl: false,
meta: false,
shift: false },
domain:
Domain {
domain: null,
_events: { error: [Function: debugDomainError] },
_eventsCount: 1,
_maxListeners: undefined,
members: [] },
_events: { line: [ [Function], [Function], [Function] ] },
_eventsCount: 1,
_maxListeners: undefined,
output:
WriteStream {
connecting: false,
_hadError: false,
_handle:
TTY {
bytesRead: 0,
_externalStream: {},
fd: 9,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread] },
_parent: null,
_host: null,
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: [Object],
length: 0,
pipes: null,
pipesCount: 0,
flowing: null,
ended: false,
endEmitted: false,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: false,
domain: null,
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
resize: [Object] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
needDrain: false,
ending: false,
ended: false,
finished: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 1,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: true,
allowHalfOpen: false,
destroyed: false,
_bytesDispatched: 22151,
_sockname: null,
_writev: null,
_pendingData: null,
_pendingEncoding: '',
server: null,
_server: null,
columns: 80,
rows: 24,
_type: 'tty',
fd: 1,
_isStdio: true,
destroySoon: [Function],
destroy: [Function] },
input:
ReadStream {
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 65536,
buffer: [Object],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: true,
endEmitted: true,
reading: false,
sync: false,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: false,
domain:
Domain {
domain: null,
_events: [Object],
_eventsCount: 1,
_maxListeners: undefined,
members: [] },
_events: { end: [Object], data: [Function: onData] },
_eventsCount: 2,
_maxListeners: undefined,
path: '/home/user/Desktop/text.txt',
fd: null,
flags: 'r',
mode: 438,
start: undefined,
end: undefined,
autoClose: true,
pos: undefined,
bytesRead: 31,
destroyed: true,
closed: true },
historySize: 30,
crlfDelay: 100,
_prompt: '> ',
terminal: true,
line: '',
cursor: 0,
history: [ '1,2,3', '4,8,4,8', '2,2,2,2', '1,2,3,4' ],
historyIndex: -1,
prevRows: 0,
paused: true,
closed: true }`
Please help I am new to this.
Your code looks fine but you are using the Node.js REPL rather than running the code from a file, which is why you're seeing this behaviour.
The Node.js REPL (what you get when you type node in terminal) will store variables. However, when only an identifier is used the value is also returned. What you're seeing isn't an error, but the rd object.
The Node.js REPL is good for testing but, unless you have a specific reason for using it, the best thing to do is create an app.js file, add your code to it and then run node app.js.
If you do need to write multi-line code using REPL, then be sure to type .editor once initialised, so that whitespace, etc. is interpreted correctly.
Also, from the 7.7.2 docs console isn't an option which createInterface is expecting, so that can be removed. In your particular example, you could also remove output: process.stdout, as your logging each line using the line event
I'm trying to create Topic For each newly created groups. So I wrote this function for doing that operation.
exports.createGroupTopic = functions.database.ref("groups/{groupid}/id")
.onWrite(event=>{
var groupid = event.params.groupid;
request({
url: "https://iid.googleapis.com/iid/v1/my_registration_token/rel/topics/topic_name",
headers: {
'Content-Type':'application/json',
'Content-Length': 0,
'Authorization':'my API Key'
}
}, function (error, response, body){
console.log(response);
});
});
But when I run this code I get the following response log on Firebase console..
IncomingMessage {
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: true,
ended: true,
endEmitted: true,
reading: false,
sync: false,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: false,
domain: null,
_events:
{ end: [ [Function: responseOnEnd], [Function] ],
close: [ [Function], [Function] ],
data: [Function],
error: [Function] },
_eventsCount: 4,
_maxListeners: undefined,
socket:
TLSSocket {
_tlsOptions:
{ pipe: null,
secureContext: [Object],
isServer: false,
requestCert: true,
rejectUnauthorized: true,
session: undefined,
NPNProtocols: undefined,
ALPNProtocols: undefined,
requestOCSP: undefined },
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: null,
npnProtocol: false,
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events:
{ close: [Object],
end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
secure: [Function],
free: [Function: onFree],
agentRemove: [Function: onRemove],
drain: [Function: ondrain],
error: [Function: socketErrorListener],
data: [Function: socketOnData] },
_eventsCount: 10,
connecting: false,
_hadError: false,
_handle: null,
_parent: null,
_host: 'iid.googleapis.com',
_readableState:
ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: [Object],
length: 0,
pipes: null,
pipesCount: 0,
flowing: true,
ended: true,
endEmitted: true,
reading: false,
sync: false,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: false,
domain: null,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
needDrain: false,
ending: true,
ended: true,
finished: true,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: true,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: false,
allowHalfOpen: false,
destroyed: true,
_bytesDispatched: 468,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: null,
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 5,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedHeader: [Object],
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Circular],
connection: [Circular],
_header: 'GET /iid/v1/my_token_id/rel/topics/TOPIC_NAME HTTP/1.1\r\nContent-Type: application/json\r\nContent-Length: 0\r\nAuthorization: api_key\r\nhost: iid.googleapis.com\r\nConnection: close\r\n\r\n',
_headers: [Object],
_headerNames: [Object],
_onPendingData: null,
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'GET',
path: '/iid/v1/fphzdEcS_D0:APA91b
Then I ran it again locally And it gave me Invalid Token Error. Then I tested the token to send direct notification. And it's working perfectly.
I don't know where is the problem. SO need help :(
This variation of your code works for me. I added the POST method and prefix key= to the Authorization value. Try it and see if it works for you.
exports.createGroupTopic = functions.database.ref("groups/{groupid}/id")
.onWrite(event => {
var groupid = event.params.groupid;
request({
method: 'POST', // <= ADDED
// ------------------- device token ------------
url: "https://iid.googleapis.com/iid/v1/cAzme9iGTO4:APA91bE...lRbx1yTei2PNFgTYGUQDUTj/rel/topics/someTopic",
headers: {
'Content-Type':'application/json',
'Content-Length': 0,
// Note below. Added: 'key='
// ----------------- server key --------------------------
'Authorization':'key=AAAAXp8june:APA91bF-Nq9pmQKr...HOES6ugO3_Xf-jV472nfn-sb'
}
}, function (error, response, body){
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
});
});
I used this function to confirm that the topic subscription was added. The returned body contains status for the device, including the topics subscribed to:
exports.checkGroupTopic = functions.database.ref("groups/check")
.onWrite(event => {
const token = 'cAzme9iGTO4:APA91bE...lRbx1yTei2PNFgTYGUQDUTj';
const serverKey = 'AAAAXp8june:APA91bF-Nq9pmQKr...HOES6ugO3_Xf-jV472nfn-sb';
request({
method: 'GET',
url: `https://iid.googleapis.com/iid/info/${token}?details=true`,
headers: {
'Content-Type':'application/json',
'Content-Length': 0,
'Authorization':`key=${serverKey}`
}
}, function (error, response, body){
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
});
});
I have a small server and small client. The code has been extrapolated to focus on the problem at hand.
I have a client that sends a POST request to the server. The server responds with a json object. I am unable to see the json response object from within the node.js client. However, if I make a curl request, I can see it...
//SERVER
var restify = require('restify'),
Logger = require('bunyan'),
api = require('./routes/api'),
util = require('util'),
fs = require('fs');
//START SERVER
var server = restify.createServer({ name: 'image-server', log: log })
server.listen(7000, function () {
console.log('%s listening at %s', server.name, server.url)
})
server.use(restify.fullResponse());
server.use(restify.bodyParser());
//change from github
var user = {username: "usr", password: "pwd"};
//auth middleware
server.use(function(req,res,next){
if(req.params.username==user.username && req.params.password == user.password){
return next();
}else{
res.send(401);
}
});
server.post('/doc/', function(req,res){
var objToJson = {"result" : "success", "user" : "simon", "location" : "someloc"};
console.log("saved new doc. res: " + util.inspect(objToJson));
res.send(objToJson);
});
//CLIENT
var formdata = require('form-data');
var request = require('request');
var util = require('util');
var fs = require('fs');
var form = new formdata();
form.append('username', 'usr');
form.append('password', 'pwd');
form.append('user', 'someemail#gmail.com');
form.append('file', fs.createReadStream('/some/file.png'));
form.append('filename', "roger123131.png");
form.submit('http://0.0.0.0:7000/doc', function(err, res) {
console.log(res.statusCode);
console.log(res.body);
console.log( "here." + util.inspect(res));
process.exit();
});
In the client, I use form-data module. I need to send over the file, though I'm not sure if this is related/pertinent to the problem at hand.
//CURL REQUEST
curl -v --form username=usr --form password=pwd --form file=#/tmp/0000b.jpg --form user=someemail http://0.0.0.0:7000/doc
The output of the curl request works. My question is, why can i not see the json response when I dump the response object in my node.js client code, but I can when making a request using curl? I'm sure the answer is simple...
EDIT: Here is the output of the node.js client, showing the response object with no evidence of the json object/string:
200
undefined
here.{ _readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: true,
calledRead: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events: { end: [Function: responseOnEnd], readable: [Function] },
_maxListeners: 10,
socket:
{ _connecting: false,
_handle:
{ fd: 10,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: true,
calledRead: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
free: [Function],
close: [Object],
agentRemove: [Function],
drain: [Function: ondrain],
error: [Function: socketErrorListener] },
_maxListeners: 10,
_writableState:
{ highWaterMark: 16384,
objectMode: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
errorEmitted: false },
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser:
{ _headers: [],
_url: '',
onHeaders: [Function: parserOnHeaders],
onHeadersComplete: [Function: parserOnHeadersComplete],
onBody: [Function: parserOnBody],
onMessageComplete: [Function: parserOnMessageComplete],
socket: [Circular],
incoming: [Circular],
maxHeaderPairs: 2000,
onIncoming: [Function: parserOnIncomingClient] },
_httpMessage:
{ domain: null,
_events: [Object],
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_headerSent: true,
_header: 'POST /doc HTTP/1.1\r\ncontent-type: multipart/form-data; boundary=--------------------------994987473640480876924123\r\nHost: 0.0.0.0:7000\r\nContent-Length: 23351\r\nConnection: keep-alive\r\n\r\n',
_hasBody: true,
_trailer: '',
finished: true,
_hangupClose: false,
socket: [Circular],
connection: [Circular],
agent: [Object],
socketPath: undefined,
method: 'POST',
path: '/doc',
_headers: [Object],
_headerNames: [Object],
parser: [Object],
res: [Circular] },
ondata: [Function: socketOnData] },
connection:
{ _connecting: false,
_handle:
{ fd: 10,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: true,
calledRead: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
free: [Function],
close: [Object],
agentRemove: [Function],
drain: [Function: ondrain],
error: [Function: socketErrorListener] },
_maxListeners: 10,
_writableState:
{ highWaterMark: 16384,
objectMode: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
errorEmitted: false },
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser:
{ _headers: [],
_url: '',
onHeaders: [Function: parserOnHeaders],
onHeadersComplete: [Function: parserOnHeadersComplete],
onBody: [Function: parserOnBody],
onMessageComplete: [Function: parserOnMessageComplete],
socket: [Circular],
incoming: [Circular],
maxHeaderPairs: 2000,
onIncoming: [Function: parserOnIncomingClient] },
_httpMessage:
{ domain: null,
_events: [Object],
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_headerSent: true,
_header: 'POST /doc HTTP/1.1\r\ncontent-type: multipart/form-data; boundary=--------------------------994987473640480876924123\r\nHost: 0.0.0.0:7000\r\nContent-Length: 23351\r\nConnection: keep-alive\r\n\r\n',
_hasBody: true,
_trailer: '',
finished: true,
_hangupClose: false,
socket: [Circular],
connection: [Circular],
agent: [Object],
socketPath: undefined,
method: 'POST',
path: '/doc',
_headers: [Object],
_headerNames: [Object],
parser: [Object],
res: [Circular] },
ondata: [Function: socketOnData] },
httpVersion: '1.1',
complete: false,
headers:
{ 'content-type': 'application/json',
'content-length': '56',
'access-control-allow-origin': '*',
'access-control-allow-headers': 'Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time',
'access-control-allow-methods': 'POST',
'access-control-expose-headers': 'Api-Version, Request-Id, Response-Time',
connection: 'Keep-Alive',
'content-md5': '/HLlB0jKu9S+l17eGyJfxg==',
date: 'Wed, 25 Jun 2014 15:40:00 GMT',
server: 'image-server',
'request-id': 'f7ca8390-fc7e-11e3-aa4e-e9c4573d9f1d',
'response-time': '4' },
trailers: {},
_pendings: [],
_pendingIndex: 0,
url: '',
method: null,
statusCode: 200,
client:
{ _connecting: false,
_handle:
{ fd: 10,
writeQueueSize: 0,
owner: [Circular],
onread: [Function: onread],
reading: true },
_readableState:
{ highWaterMark: 16384,
buffer: [],
length: 0,
pipes: null,
pipesCount: 0,
flowing: false,
ended: false,
endEmitted: false,
reading: true,
calledRead: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null },
readable: true,
domain: null,
_events:
{ end: [Object],
finish: [Function: onSocketFinish],
_socketEnd: [Function: onSocketEnd],
free: [Function],
close: [Object],
agentRemove: [Function],
drain: [Function: ondrain],
error: [Function: socketErrorListener] },
_maxListeners: 10,
_writableState:
{ highWaterMark: 16384,
objectMode: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
decodeStrings: false,
defaultEncoding: 'utf8',
length: 0,
writing: false,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
errorEmitted: false },
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser:
{ _headers: [],
_url: '',
onHeaders: [Function: parserOnHeaders],
onHeadersComplete: [Function: parserOnHeadersComplete],
onBody: [Function: parserOnBody],
onMessageComplete: [Function: parserOnMessageComplete],
socket: [Circular],
incoming: [Circular],
maxHeaderPairs: 2000,
onIncoming: [Function: parserOnIncomingClient] },
_httpMessage:
{ domain: null,
_events: [Object],
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_headerSent: true,
_header: 'POST /doc HTTP/1.1\r\ncontent-type: multipart/form-data; boundary=--------------------------994987473640480876924123\r\nHost: 0.0.0.0:7000\r\nContent-Length: 23351\r\nConnection: keep-alive\r\n\r\n',
_hasBody: true,
_trailer: '',
finished: true,
_hangupClose: false,
socket: [Circular],
connection: [Circular],
agent: [Object],
socketPath: undefined,
method: 'POST',
path: '/doc',
_headers: [Object],
_headerNames: [Object],
parser: [Object],
res: [Circular] },
ondata: [Function: socketOnData] },
_consuming: true,
_dumped: false,
httpVersionMajor: 1,
httpVersionMinor: 1,
upgrade: false,
req:
{ domain: null,
_events: { error: [Object], response: [Function] },
_maxListeners: 10,
output: [],
outputEncodings: [],
writable: true,
_last: false,
chunkedEncoding: false,
shouldKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_headerSent: true,
_header: 'POST /doc HTTP/1.1\r\ncontent-type: multipart/form-data; boundary=--------------------------994987473640480876924123\r\nHost: 0.0.0.0:7000\r\nContent-Length: 23351\r\nConnection: keep-alive\r\n\r\n',
_hasBody: true,
_trailer: '',
finished: true,
_hangupClose: false,
socket:
{ _connecting: false,
_handle: [Object],
_readableState: [Object],
readable: true,
domain: null,
_events: [Object],
_maxListeners: 10,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser: [Object],
_httpMessage: [Circular],
ondata: [Function: socketOnData] },
connection:
{ _connecting: false,
_handle: [Object],
_readableState: [Object],
readable: true,
domain: null,
_events: [Object],
_maxListeners: 10,
_writableState: [Object],
writable: true,
allowHalfOpen: false,
onend: [Function: socketOnEnd],
destroyed: false,
bytesRead: 587,
_bytesDispatched: 23536,
_pendingData: null,
_pendingEncoding: '',
parser: [Object],
_httpMessage: [Circular],
ondata: [Function: socketOnData] },
agent:
{ domain: null,
_events: [Object],
_maxListeners: 10,
options: {},
requests: {},
sockets: [Object],
maxSockets: 5,
createConnection: [Function] },
socketPath: undefined,
method: 'POST',
path: '/doc',
_headers:
{ 'content-type': 'multipart/form-data; boundary=--------------------------994987473640480876924123',
host: '0.0.0.0:7000',
'content-length': 23351 },
_headerNames:
{ 'content-type': 'content-type',
host: 'Host',
'content-length': 'Content-Length' },
parser:
{ _headers: [],
_url: '',
onHeaders: [Function: parserOnHeaders],
onHeadersComplete: [Function: parserOnHeadersComplete],
onBody: [Function: parserOnBody],
onMessageComplete: [Function: parserOnMessageComplete],
socket: [Object],
incoming: [Circular],
maxHeaderPairs: 2000,
onIncoming: [Function: parserOnIncomingClient] },
res: [Circular] },
pipe: [Function],
addListener: [Function],
on: [Function],
pause: [Function],
resume: [Function],
read: [Function] }
from the docs,
form.submit('http://example.org/', function(err, res) {
// res – response object (http.IncomingMessage) //
res.resume(); // for node-0.10.x
});
Your callback has three parameters, and the response is in the second one.
I found a solution from the the request page (https://github.com/mikeal/request), which requires a small change to the client code:
var r = request.post('http://service.com/upload', function optionalCallback (err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
})
var form = r.form()
form.append('my_field', 'my_value')
form.append('my_buffer', new Buffer([1, 2, 3]))
form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png')))
form.append('remote_file', request('http://google.com/doodle.png'))