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