1 /*global module: true */ 2 3 /** 4 * @overview: Surfaces API feature of the GCN JS API which are NodeJS specific. 5 */ 6 (function (GCN) { 7 8 'use strict'; 9 10 if (!GCN.global.isNode) { 11 GCN.FolderAPI.prototype.createFile = function (file, success, error) { 12 GCN.handleError(GCN.createError('UNAVAILABLE_FEATURE', 13 'createFile() functionality is only available when using the' + 14 'GCN JS API in Node.js environment.'), error); 15 }; 16 return; 17 } 18 19 var fs = require('fs'); 20 var url = require('url'); 21 var path = require('path'); 22 var http = require('http'); 23 var https = require('https'); 24 var mime = require('mime'); 25 26 /** 27 * Performs HTTP requests, including POST and GET. 28 * 29 * @private 30 * @param {string} uri The URI to send the request to. 31 * @param {object} options A object specifying options to use in the HTTP 32 * request. 33 * @param {function(string)} callback A function that will receive the HTTP 34 */ 35 function httpRequest(uri, options, callback) { 36 if (typeof options === 'function') { 37 callback = options; 38 options = {}; 39 } 40 var defaultPort; 41 var protocol; 42 if (!/^https?\:\/\//.test(uri)) { 43 uri = 'http://' + uri; 44 defaultPort = 80; 45 protocol = http; 46 } else { 47 defaultPort = 443; 48 protocol = https; 49 } 50 var urlSegments = url.parse(uri); 51 var data = (typeof options.data !== 'undefined') ? options.data : ''; 52 var settings = { 53 host: urlSegments.host, 54 port: urlSegments.port || defaultPort, 55 path: urlSegments.path, 56 method: options.method || 'GET', 57 headers: { 58 'Content-Length': data.length 59 } 60 }; 61 var header; 62 for (header in options.headers) { 63 if (options.headers.hasOwnProperty(header)) { 64 settings.headers[header] = options.headers[header]; 65 } 66 } 67 var request = protocol.request(settings, function (response) { 68 var responseText = []; 69 response.setEncoding('utf8'); 70 response.on('data', function (chunk) { 71 responseText.push(chunk); 72 }); 73 response.on('end', function () { 74 callback(responseText.join(''), response); 75 }); 76 }); 77 if (options.data) { 78 request.write(options.data); 79 } 80 request.end(); 81 } 82 83 /** 84 * Uploads a file at the given location and creates correspoding file 85 * content object for it in the GCN backend. 86 * 87 * @public 88 * @function 89 * @name createFile 90 * @memberOf GCN.FolderAPI 91 * @param {string} file The relative path to the file to be uploaded. 92 * @param {function(GCN.File)} success A callback that will receive the 93 * created file object as its only 94 * argument. 95 * @param {function(GCNError):boolean=} error An optional custom error 96 * handler. 97 * @return {undefined} 98 */ 99 GCN.FolderAPI.prototype.createFile = function (file, success, error) { 100 var folder = this; 101 this._read(function () { 102 fs.readFile(file, function (err, data) { 103 if (err) { 104 GCN.handleError(GCN.createError('UPLOAD_FAILED', 105 'Could not upload file: ' + file, err), error); 106 return; 107 } 108 var url = GCN.settings.BACKEND_PATH 109 + '/rest/file/createSimple?sid=' + GCN.sid 110 + '&folderId=' + folder.id() 111 + '&qqfile=' + path.basename(file) 112 + GCN._getChannelParameter(folder, '&'); 113 114 httpRequest(url, { 115 method: 'POST', 116 headers: { 117 'Content-Type': mime.lookup(file), 118 'Accept': 'application/json' 119 }, 120 data: data 121 }, function (responseText, response) { 122 folder.handleUploadResponse(JSON.parse(responseText), 123 success, error || function () {}); 124 }); 125 }); 126 }, error); 127 }; 128 129 module.exports = GCN; 130 131 }(GCN)); 132