Skip to content Skip to sidebar Skip to footer

How to Use Ftp to Upload Files to a Website on Andrew

Earth to Mercury — Send me the files!

For my next project, my mentors tasked me with building an FTP server in Java.

In the past I've used an FTP server to upload files to a website (back when I was making Wordpress sites without version command!! 😣) just I had no thought how an FTP server actually works under the hood. Well I was most to notice out!

You can check out lawmaking here: https://github.com/andrewMacmurray/mercury-ftp

An FTP server is a server that you tin can send and receive files from — think of it like a dedicated Dropbox or Google Drive. FTP stands for File Transfer Protocol — a set of rules defining how an FTP server and client should communicate.

I decided to name my server mercury — because every project needs a skillful name! We spend so much effort naming things in our programs, why not spend the aforementioned care on the project name itself.

Mercury was an ancient Roman god¹, the winged messenger, and keeper of boundaries. He could travel freely between the mortal and divine realms and would ferry souls to the afterlife. Mercury the liquid metal is also a nice visual metaphor describing files in transit between the cloud and the mortal realm of our computers!

I'd imagined a logo like this for a web customer, but alas not enough time to do the whole thing:

https://codepen.io/andrewmacmurray/project/full/DyMEYz/

After a bit of digging around in the RFC document for the FTP spec (and a good bit of googling) I understood the core concepts of an FTP server revolve around two server connections

  • A Command connection — one where commands and responses are sent between the customer and server
  • A File or Information connection — where file data is sent back and forth

When a client connects to the server the Command connectedness is kept open up for the entire session, only the data connectedness is ephemeral — it springs to life and and so dies for each file sent.

A Typical Conversation

Clients can ship the server a series of 3–iv letter of the alphabet commands followed by 0 or more arguments. So a conversation might become like this:

The client sends a string to the server's Command connectedness

          RETR hello.txt        

Which is interpreted as "hey server retrieve the file hello.txt for me please"

The server opens its Data connection and sends the contents of hello.txt to the client.

The server then responds to the client over the Command connection with in the format response-code message:

          250 hello.txt sent        

Or an error if the file could not be sent

          450 could not retrieve file, does not exist        

I function of the application I'thousand specially proud of is how I implemented the data connexion.

The data connection involved opening a network Socket and either reading file data from its InputStream or writing file data to its OutputStream and then making certain the streams and Socket shut afterwards the operation is done. Sockets and files can be very resources intensive and so information technology's of import to shut them after they're no longer needed.

Close me properly

InputStream, OutputStream and Socket tin can all throw IOExceptions on many of their operations — this can make closing them properly a little tricky. Pre Coffee seven doing something with 1 of these resources would involve a try / take hold of / finally block:

          endeavour {
InputStream inputStream = socket.getInputStream();
Cord line = inputStream.readLine();
doSomethingWith(line);
} catch (IOException due east) {
reportError(due east.getMessage);
} finally {
inputStream.close();
}

Using this block ensures that the inputStream is airtight — either after the attempt cake completes or if an error is thrown — which is great!

But, this code is ugly, and we take to include it everywhere we want to do something with an InputStream (or any closeable resource).

Java seven added a nicer syntax for this — the try with resource argument — and so the above could exist written as:

          effort (InputStream inputStream = socket.getInputStream()) {
String line = inputStream.readLine();
doSomethingWith(line);
} catch (IOException e) {
reportError(e.getMessage());
}

The effort with resources block works with whatsoever object that implements the AutoCloseable interface (each object has to implement a close method).

Nosotros tin get ane pace further ensuring this closing happens properly past making use of Coffee eight'southward lambdas! Reading a affiliate on using lambda expressions to handle resource in the fantastic book Functional Programming in Java, got me thinking if I could utilise the same pattern with my sockets.

The Execute Around Method pattern (EAM)

Wouldn't it exist nice if any consumers of my socket streams can only utilize a stream if it'due south wrapped in a attempt with resources block? With lambdas there's a clean way to enforce this.

I created two specialised types of lambdas — each of which would receive either an InputStream or OutputStream and could practice whatever they needed with it. Here'south the one for InputStream:

          @FunctionalInterface
public interface InputStreamAction {

void runWithStream(InputStream inputStream) throws IOException;

}

The class where the data socket magic happens I've chosen a SocketExecutor — the trick here is that it exposes two methods (runInputStream and runOutputStream) that take a lambda expression as an argument:

          public void runInputStream(InputStreamAction inputStreamAction) throws IOException {
attempt (
Socket socket = createSocket();
InputStream inputStream = socket.getInputStream();
) {
inputStreamAction.runWithStream(inputStream);
}
}

This may expect weird at first merely it has quite a powerful effect — the only manner of interacting with a socket stream is via the endeavour with resources block! Information technology's at present incommunicable to forget to shut the resources ✨ . This is also known every bit the "Execute Around Method pattern" the resource cleanup is "executed effectually" an activity (or method) that needs to be performed.

Consumers of this api now don't need to care most where the InputStream or OutputStream came from, they only demand to apply information technology.

Some of the methods in my FtpFileSystem class ended up looking like this:

          public InputStreamAction store(String path) {
render inputStream -> fs.writeFile(path, inputStream);
}

The shop method now returns a lambda that volition receive information from an InputStream and write it to the fileSystem.

All in all it was a very interesting practice in seeing how ideas from functional programming help enforce skilful OO design principles — Unmarried Responsibility and separation of concerns.

After setting upwardly the SocketExecutor I got a bit too lambda happy! I started using lambdas effectively to pluck single methods from classes for utilize in other classes where peradventure I could take designed those classes a little more thoughtfully.

This had the effect of making the code quite difficult to follow at times — one of the crafters looked at my code and said

"is this how the kids write Java these days?"

which made me express joy! But was a very valid bespeak — trying to be besides clever is often not the best idea. Others will exist less likely to want to extend the code and it could become a liability in the future.

I felt the SocketExecutor yet was a skilful balance betwixt the benefits it offered and the overhead of it'due south unusual idiom.

I had a lot of fun making the FTP server. Even though I couldn't implement all of the core spec in time it turned out to be quite a large project! I experience I learnt a lot about managing complexity not to mention Sockets, Streams and Files galore!

Stay tuned for a post on sending Mercury up to the cloud!

ane — The Roman god Mercury is also effectively stolen from Greek mythology where Hermes is the winged messenger. Mercury is a pale faux of the real matter (much like my server as information technology currently stands 😂).

williamsgrayoucand.blogspot.com

Source: https://medium.com/@andrewMacmurray/earth-to-mercury-send-me-the-files-716af12e94a4

Post a Comment for "How to Use Ftp to Upload Files to a Website on Andrew"