I am currently designing a system that lets users connect their Cloud Storage such as Google Drive, Dropbox etc and also to their physical filesystem (personal laptop/ ftp server etc.) and then can just open a single webpage page where he can find all the files in each of the storages and can download them. My system has 3 main components which are

  • A front end UI which the user will use to view files from all the different storage providers (React frontend)
  • A backend server which does authentication using a DB (Mongo) and once authenticated, creates connections to the different storage providers. (Nodejs server)
  • A backend client to be run ONLY on the physical filesystem (personal laptop) which will connect to the server to provide the files in the file system. (Node js client server)

Now, I also provide the ability for multiple users to connect to the server, authenticate themselves and have access to their storage. (I decided to use the Google API and Dropbox API to connect to the server (using OAuth) and store their tokens in the DB so that they don't have to authenticate every time for fetching the files.)

So far, I think my design looks solid, except for the File System client part. I decided to use Web Sockets for this ie. the client will connect to the server by providing credentials, and once authenticated, the server will generate a unique UUID and store it along with the user details in the DB and also send the UUID to the client on successful authentication. The client will verify the token for every emit from the server. So now the flow is as

  • Everytime the user requests a file from the FS (File System), he will send the token along with the emit request.
  • The client verifies if the token matches with what it received during authentication and if true, will send the file.

Now, this is where my doubt is.

Since multiple users can be connected to the server and each might have their FS connection open using sockets, is it right that every time a user requests a file from his File System, all the other user's client also checks if their token matches?

I feel this part of the design is problematic.

Of course, inactive clients will timeout and their connection would be closed, but suppose if 1000 users are actively using the application, then whenever user 1 requests a file from his file system, the emitted event from the server with the UUID for user 1 would also trigger all the other 999 users to check if the token matches theirs.

Is there also a security concern here?

The only reason I wanted to have a socket connection is so that connecting the FS client to the server would require constant connection as long as the FS is alive and I don't know if HTTP requests would be secure as the port of the client would be exposed to the outside world.

Please give me your valuable thoughts on this.

  • You forgot two essential elements in your question: what is your time budget (in how many months should you deliver your code) and what is your money budget (can you afford spending a million euros or US dollars) – Basile Starynkevitch Mar 12 at 6:47

Is using web sockets between client-server to transfer files the right approach?

It concretely depends upon the size of the file. And remember that files practically have a MIME type (and a file name, which might be relevant; e.g. file names ending with .jpeg are conventionally JPEG files).

If you share less than a thousand bytes, be aware that it usually would take more than 1K of disk space. Because most file systems organize files in multiple of the disk block size (512 bytes or 4Kbytes on SATA). The figure about Ext2 is explaining that easily (but the principle is probably relevant for NTFS). If your file system has directories, be aware to limit their size to a suitable threshold (so prefer having ten thousand files organized in several directories named  01/abc12.jpeg, 03/cde2.c, etc... to have a single directory of ten thousand files 01abc12.jpeg, 03cde2.c etc...). Read a textbook on operating systems and more about HTTP and other protocols (e.g. SMTP ...) and open formats (e.g. HTML5, PDF, ZIP, SVG, MP3, Ogg, MPEG-4) involved in the World Wide Web.

If you share 100 kilobytes, sending that on a websocket makes sense. You probably want to also share the MIME type and in practice send some JSON on the websocket and code some JavaScript AJAX thing to extract it.

If you share a file of ten megabytes (e.g. some MPEG-4 video), sharing a unique URL makes more sense. Because sending ten megabytes usually takes a few seconds. That URL could be in practice random and nearly globally unique (like UUID are), e.g. https://example.com/0cSUtWqTYdZ0z18rx

This discussion on the maximal size of sqlite databases is related to your question. You may want to use some Sqlite database to implement your solution.

See also both bismon and RefPerSys.

On Linux, read path_resolution(7). Be also aware of the C10K problem. On current Linux servers, a single process (e.g. some lighttpd web server) can have ten thousand tcp(7) sockets (but not a million one). See also proc(5), getrlimit(2) and socket(7).

Your code and approach would be different if you want to share 400 gigabytes of data (on some SSD disk) with a thousand users or a petabyte of data (in a datacenter) with a million simultaneous users. Read about cloud computing, Docker, OpenStack. That is why companies like Google or FaceBook employ many thousand engineers.

See also these slides that I presented recently (in March 2020) and are indirectly related to your concerns. In practice, size and time matters. Size of data, size of development team, development time, Web server response time, etc... Of cours also, budget size: what time constraints do you have, how many kilo€ or mega€ (or US$, or Indian Rupies, ....) can you afford to spend.

And the devil is in the details.

... including your cybersecurity concerns: if you want to hide from the NSA you need more budget that to avoid the random teenager hacker against which avoiding code injection — notably SQL injection, see this — and buffer overflows is enough; but protecting your website against DDOS attacks is much more difficult. You should find and contact the equivalent of ANSSI in India, probably India's National Cyber Cordination Center. Of course use HTTPS, not just HTTP.

Be also aware of regulations related to privacy. In principle, the GDPR may apply to your website as soon as you have European users (at least if they are buying services or goods on the Web). But I am not a lawyer, and you may need to pay one.

| improve this answer | |
  • Thanks for the reply. Yes, the file sizes would actually be in the range of 10-20mb. Also I thought I will use streams to to this. Do I still need to consider what you have explained even if I use streams ? Also my biggest doubt was using web sockets in the first place due to large number of users connected at the same time where they will have to check if the file request is for them or not based on the UUID I pass from the server. – v1shnu Mar 12 at 6:21
  • Ask yourself: how much data do you want to manage and share (gigabytes or petabytes), and how many simultaneous users do you want to accept (a thousand HTTP connections, or a million one). ask also for the available budget (10k€ or 10M€) and development time (months or years) and size of development team (2 engineers or a hundred of them). – Basile Starynkevitch Mar 12 at 6:35
  • Your major concern is: what budget do you have (in data size, in computer hardware, in development efforts). – Basile Starynkevitch Mar 12 at 6:40
  • @v1shnu: if you feel the reply is relevant, upvote it. – Basile Starynkevitch Mar 12 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.