Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[CLEANUP] refactored somewhat heavily

  • Loading branch information...
commit 2805b2298509c12c58e31419efd2f713fe73258b 1 parent 2a3a750
@coolaj86 authored
View
3  .gitignore
@@ -1 +1,4 @@
node_modules
+files
+*.swp
+*.swo
View
202 LICENSE.APACHE2
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2011 AJ ONeal, Jamison Dance
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
View
31 README.md
@@ -6,6 +6,11 @@ Dropshare is a shameless [ge.tt](http://ge.tt) / [min.us](http://min.us) clone.
This contains both a server and clients (curl and browser)
Dropshare-server is the server for a simple ge.tt or min.us clone.
+Install
+===
+
+ 0. Install `redis`. See Appendix (below) for installing redis on OS X.
+
LICENSE
===
@@ -13,3 +18,29 @@ Dropshare is available under the following lincenses:
* MIT
* Apache 2
+
+Appendix
+===
+
+Installing Redis
+---
+
+ brew install redis
+
+ mkdir -p ~/Library/LaunchAgents
+
+ launchctl unload -w ~/Library/LaunchAgents/io.redis.redis-server.plist 2>/dev/null || true
+ cp /usr/local/Cellar/redis/2.2.12/io.redis.redis-server.plist ~/Library/LaunchAgents/
+ launchctl load -w ~/Library/LaunchAgents/io.redis.redis-server.plist
+
+**To start redis manually:**
+
+ redis-server /usr/local/etc/redis.conf
+
+**To access the server:**
+ redis-cli
+
+Ubuntu Linux
+---
+
+ sudo apt-get install redis
View
12 bin/dropshare.js
@@ -0,0 +1,12 @@
+#!/usr/bin/env node
+(function () {
+ "use strict";
+
+ var dropshare = require('dropshare')
+ , port = process.argv[2] || 3700 // 37 === DS
+ ;
+
+ dropshare.create().listen(port);
+
+ console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
+}());
View
7 config.default.js
@@ -0,0 +1,7 @@
+(function () {
+ "use strict";
+
+ module.exports = {
+ "port": 3700
+ };
+}());
View
0  files/.keep
No changes.
View
70 lib/gen-id.js
@@ -0,0 +1,70 @@
+ (function () {
+ "use strict";
+
+ var removeTrailingEqualsRegex = /([a-zA-Z0-9\+\/]+)=+/
+ , numericBuffer = require('numeric-buffer')
+ ;
+
+ function create(timestamp) {
+ // Generate a fairly unique ID for file uploads.
+ // Use the difference between a passed in time and the
+ // current timestamp in seconds, along with a random integer
+ // appended to that, to generate the id.
+ // Note: this is not actually very secure, consequences of
+ // someone guessing someone else's unique id are low, so
+ // it is not a big deal.
+ // TODO: pull this out into a separate file
+ var randomInts = []
+ , i = 0
+ ;
+
+ function createRandomBits() {
+ for (i; i < 10000; i += 1) {
+ randomInts[i] = i;
+ }
+
+ //Sort in random order
+ randomInts.sort(function (a, b) {
+ return Math.random() - 0.5;
+ });
+ }
+
+ return function () {
+ var randomSuffix
+ , now = Date.now()
+ , id
+ , base64Id
+ ;
+
+ // Difference between timestamp and passed in time in seconds
+ id = parseInt((now - timestamp) / 1000, 10).toString();
+
+ // If we have used up all the random integers,
+ // re-sort them and start again at the beginning of the random integers.
+ if (!randomInts.length) {
+ createRandomBits();
+ }
+ randomSuffix = randomInts.pop();
+
+ id += randomSuffix;
+ id = parseInt(id, 10);
+
+ // Convert the int into a base64 string
+ base64Id = numericBuffer(id).toString('base64');
+ base64Id = base64Id.replace(removeTrailingEqualsRegex, "$1");
+
+ return base64Id;
+ };
+ }
+
+ module.exports.create = create;
+ /*
+ var genId = create(Date.now() - 645483);
+ console.log(genId());
+ console.log(genId());
+ console.log(genId());
+ console.log(genId());
+ console.log(genId());
+ console.log(genId());
+ */
+ }());
View
153 lib/index.js
@@ -5,41 +5,29 @@
*/
var express = require('express')
+ , connect = require('connect')
, util = require('util')
, fs = require('fs')
, assert = require('assert')
- , numericBuffer = require('numeric-buffer')
, Futures = require('futures')
, Formaline = require('formaline')
- , redisWrapper = require('./redis-wrapper')
- , installTime
- , storage = new redisWrapper();
+ // The DropShare Epoc -- 1320969600000 -- Fri, 11 Nov 2011 00:00:00 GMT
+ , generateId = require('./gen-id').create(1320769600000)
+ , storage = require('./redis-wrapper').create()
+ , filesDir = __dirname + '/files'
+ , app
+ ;
- var app = module.exports = express.createServer();
+ connect.cors = require('connect-cors');
- // Configuration
- app.configure(function(){
- //get first start time, or create it if it does not exist
- fs.readFile('install_time.txt', function (err, data) {
- var time = Date.now();
- if (err) {
- fs.writeFile('install_time.txt', time.toString(), function (err) {
- if (err) {
- throw err;
- }
- console.log("install_time written out!");
- installTime = time;
- });
- }
- else {
- console.log("install_time found, and it is " + data);
- installTime = parseInt(data, 10);
- }
- });
+ app = express.createServer();
+ // Configuration
+ app.configure(function () {
+ //app.use(connect.cors());
app.use(express.bodyParser());
- app.use(express.methodOverride());
- app.use(app.router);
+ //app.use(express.methodOverride());
+ //app.use(express.router());
app.use(express.static(__dirname + '/public'));
});
@@ -51,83 +39,34 @@
app.use(express.errorHandler());
});
-
- // Generate a fairly unique ID for file uploads.
- // Use the difference between a passed in time and the
- // current timestamp in seconds, along with a random integer
- // appended to that, to generate the id.
- // Note: this is not actually very secure, consequences of
- // someone guessing someone else's unique id are low, so
- // it is not a big deal.
- // TODO: pull this out into a separate file
- var generateID = (function () {
- var randomInts = []
- , i = 0
- , counter = 0
-
-
- for (i; i < 10000; i++) {
- randomInts[i] = i;
- }
-
- //Sort in random order
- randomInts.sort(function (a, b) {
- return Math.random() - 0.5;
- });
-
- return function (startTime) {
- var randomSuffix
- , now = Date.now()
- , id
- , idString
- , removeTrailingEqualsRegex;
-
- // Difference between startTime and passed in time in seconds
- id = parseInt((now - startTime) / 1000, 10).toString();
-
- // If we have used up all the random integers,
- // re-sort them and start again at the beginning of the random integers.
- if (counter >= randomInts.length) {
- randomInts.sort(function (a, b) {
- return Math.random() - 0.5;
- });
- counter = 0;
- }
- randomSuffix = randomInts[counter];
-
- id += randomSuffix;
-
- id = parseInt(id, 10);
- // Convert the int into a base64 string
- idString = numericBuffer(id).toString('base64');
- removeTrailingEqualsRegex = /([a-zA-Z0-9\+\/]+)=+/;
- idString = idString.replace(removeTrailingEqualsRegex, "$1");
- counter += 1;
- return idString;
- };
- }());
-
// Routes
- app.post('/files/new', function (req, res, next) {
+ function createIds(req, res, next) {
var i
- , sequence = Futures.sequence()
- , ids = []
- , id
- , err
+ , sequence = Futures.sequence()
+ , ids = []
+ , id
+ , meta
+ , err
+ , now = Date.now()
+ ;
if (!req.body instanceof Array) {
var err = {
"result": "error",
"data": "Must be an array of file metadata."
};
+
res.send(JSON.stringify(err), 400);
return;
}
+ // TODO use forEachAsync
for (i = 0; i < req.body.length; i++) {
- id = generateID(installTime);
+ meta = req.body[i];
+ meta.timestamp = now;
+ id = generateId();
sequence.then(function (next) {
- storage.set(id, req.body[i], function (err, data) {
+ storage.set(id, meta, function (err, data) {
ids.push(id);
next();
});
@@ -138,7 +77,7 @@
res.send(JSON.stringify(ids));
next();
});
- });
+ }
function handleUploadedFiles (json, res) {
var responses = [];
@@ -177,7 +116,7 @@
console.log("calling moveFileToStorage");
var is
, os
- , newFilePath = 'files/' + file.sha1checksum;
+ , newFilePath = filesDir + '/' + file.sha1checksum;
fs.stat(file.path, function (err, stat) {
assert.strictEqual(err, null, "tried to move a non-existent file");
@@ -215,7 +154,7 @@
return JSON.stringify(responses);
}
- app.post('/files', function (req, res, next) {
+ function receiveFiles(req, res, next) {
var form
, config;
@@ -236,9 +175,9 @@
form = new Formaline(config);
form.parse(req, res, handleUploadedFiles);
- });
+ }
- app.get('/files/:id/:filename?', function (req, res, next) {
+ function sendFile(req, res, next) {
/*
* 1. Check if a file exists for that id
* 2. if so, allow them to download the file with the given filename
@@ -258,19 +197,33 @@
return;
}
- fs.readFile('files/' + data.sha1checksum, function (err, fileData) {
+ fs.readFile(filesDir + '/' + data.sha1checksum, function (err, fileData) {
+ if (err) {
+ throw err;
+ }
+
res.writeHead(200, {'content-type': data.type });
+ console.log('fdata:', fileData);
res.write(fileData);
res.end();
});
});
- });
+ }
+
+ function removeFile(req, res, next) {
+ res.end('Not Supported Yet');
+ }
- // app.delete('/files/:id', function (req, res, next) {
+ app.post('/files/new', createIds);
+ app.post('/files', receiveFiles);
+ app.get('/files/:id/:filename?', sendFile);
+ app.delete('/files/:id', removeFile);
- // });
+ function create(options) {
+ filesDir = options.files;
+ return app;
+ }
- app.listen(3333);
- console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
+ module.exports.create = create;
}());
View
6 lib/redis-wrapper.js
@@ -41,5 +41,9 @@
};
}
- module.exports = RedisWrapper;
+ function create() {
+ return new RedisWrapper();
+ };
+
+ module.exports.create = create;
}());
View
3  package.json
@@ -14,7 +14,7 @@
"test": "dropshare 4567"
},
"engines": {
- "node": "~0.4.8"
+ "node": "~0.4.x"
},
"dependencies": {
"connect": "*"
@@ -25,6 +25,7 @@
, "redis": "0.6.x"
, "futures": "2.3.x"
, "formaline": "0.6.x"
+ , "numeric-buffer": "0.1.0"
},
"devDependencies": {}
}
View
14 server.js
@@ -0,0 +1,14 @@
+(function () {
+ "use strict";
+
+ var dropshare = require('./lib/index')
+ , options = {
+ "tmp": "/tmp"
+ , "files": __dirname + "/files"
+ , "client": "./public"
+ }
+ , server = dropshare.create(options)
+ ;
+
+ module.exports = server;
+}());
View
4 lib/test.sh → tests/test.sh
@@ -1,6 +1,8 @@
#! /bin/bash
-HOST="http://localhost:3333"
+# npm install -g json-cherry-pick
+
+HOST="http://localhost:3700"
RESULT=`curl "${HOST}/files/new" -X POST \
-H "Content-Type: application/json" \
Please sign in to comment.
Something went wrong with that request. Please try again.