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 mime = require('mime');
 24 
 25 	/**
 26 	 * Performs HTTP requests, including POST and GET.
 27 	 *
 28 	 * @private
 29 	 * @param {string} uri The URI to send the request to.
 30 	 * @param {object} options A object specifying options to use in the HTTP
 31 	 *                         request.
 32 	 * @param {function(string)} callback A function that will receive the HTTP
 33 	 */
 34 	function httpRequest(uri, options, callback) {
 35 		if (typeof options === 'function') {
 36 			callback = options;
 37 			options = {};
 38 		}
 39 		if (!/^https?\:\/\//.test(uri)) {
 40 			uri = 'http://' + uri;
 41 		}
 42 		var urlSegments = url.parse(uri);
 43 		var data = (typeof options.data !== 'undefined') ? options.data : '';
 44 		var settings = {
 45 			host: urlSegments.host,
 46 			port: urlSegments.port || 80,
 47 			path: urlSegments.path,
 48 			method: options.method || 'GET',
 49 			headers: {
 50 				'Content-Length': data.length
 51 			}
 52 		};
 53 		var header;
 54 		for (header in options.headers) {
 55 			if (options.headers.hasOwnProperty(header)) {
 56 				settings.headers[header] = options.headers[header];
 57 			}
 58 		}
 59 		var request = http.request(settings, function (response) {
 60 			var responseText = [];
 61 			response.setEncoding('utf8');
 62 			response.on('data', function (chunk) {
 63 				responseText.push(chunk);
 64 			});
 65 			response.on('end', function () {
 66 				callback(responseText.join(''), response);
 67 			});
 68 		});
 69 		if (options.data) {
 70 			request.write(options.data);
 71 		}
 72 		request.end();
 73 	}
 74 
 75 	/**
 76 	 * Uploads a file at the given location and creates correspoding file
 77 	 * content object for it in the GCN backend.
 78 	 *
 79 	 * @public
 80 	 * @function
 81 	 * @name createFile
 82 	 * @memberOf GCN.FolderAPI
 83 	 * @param {string} file The relative path to the file to be uploaded.
 84 	 * @param {function(GCN.File)} success A callback that will receive the
 85 	 *                                     created file object as its only
 86 	 *                                     argument.
 87 	 * @param {function(GCNError):boolean=} error An optional custom error
 88 	 *                                            handler.
 89 	 * @return {undefined}
 90 	 */
 91 	GCN.FolderAPI.prototype.createFile = function (file, success, error) {
 92 		var folder = this;
 93 		this._read(function () {
 94 			fs.readFile(file, function (err, data) {
 95 				if (err) {
 96 					GCN.handleError(GCN.createError('UPLOAD_FAILED',
 97 						'Could not upload file: ' + file, err), error);
 98 					return;
 99 				}
100 				var url = GCN.settings.BACKEND_PATH
101 						+ '/rest/file/createSimple?sid=' + GCN.sid
102 						+ '&folderId=' + folder.id()
103 						+ '&qqfile=' + path.basename(file);
104 
105 				httpRequest(url, {
106 					method: 'POST',
107 					headers: {
108 						'Content-Type': mime.lookup(file),
109 						'Accept': 'application/json'
110 					},
111 					data: data
112 				}, function (responseText, response) {
113 					folder.handleUploadResponse(JSON.parse(responseText),
114 						success, error || function () {});
115 				});
116 			});
117 		}, error);
118 	};
119 
120 	module.exports = GCN;
121 
122 }(GCN));
123