The grep command in Unix and Linux and its common usage

Monday, December 29, 2008

I have been using the grep command in UNIX virtually everyday in my work but yet sometimes some of the file manipulation tasks annoy me, especially the pattern matching tasks for which I always needed a quick solution, so I decided to do a writeup on grep command and its practical applications, hope this may make the life of UNIX users a little easier.


The grep series of commands.... For a customary introduction, the grep command is used to find/print lines in a file that matches a pattern, it comes in different flavors, there is an enhanced version of the grep command, namely the egrep which does some advanced regular expression pattern matching on text files and the fgrep command which is used to search text in a file without any regular expession interpretation of the search pattern.


Some common grep usage options....

grep pattern filenames - Displays lines in files which matches the pattern.
grep -i pattern filenames - Displays lines in files which matches the pattern, ignores case while matching the pattern.
grep -c pattern filenames - Prints the count of the number of lines which matches the pattern in files.
grep -l pattern filenames - Lists the names of files which matches the pattern along with the lines which matched the pattern.

Similarly egrep command is used with different enhanced pattern matching options used with regular expressions like

egrep (x|y) filename - Displays lines which match the pattern x or y.
egrep (x|y)+ filename - Displays lines which matches atleast one or more text x or y.

fgrep is mainly used to avoid using search patterns as regular expressions or metacharacters

fgrep '*' filename - matches the occurence of pattern * in filenames, note here * doesn't mean a regular expression or a metacharacter.

Applications of grep command:

grep
command can be used as a standalone utility to match a pattern in a file or piped to other utility commands like sed or awk to manilupate and extract text fom files, some of the common applications of grep from simple to little tricky ones are shown below.

The text file used to illustrate the below grep commands is shown below.
bash-3.00# cat textfile.txt 
This is line 1
This is line 2
This is line 3
This is line 4
This is line 5
bash-3.00#

1. Displaying or Saving a file with line numbers

There are several ways to save or display a text file with line numbers, some of them are
bash-3.00# grep -n '^' textfile.txt 
1:This is line 1
2:This is line 2
3:This is line 3
4:This is line 4
5:This is line 5
The above command matches the first line of the input file ('^' matches a pattern at the beginning of a line), or it matches all the lines in a file, one can also use grep -n '$' textfile.txt to produce the same output (the regular expression '$' means "ends with").
bash-3.00# grep -n '$' textfile.txt 
1:This is line 1
2:This is line 2
3:This is line 3
4:This is line 4
5:This is line 5
Also one can use the Regular expression ".*" to match and print all lines in the file with line numbers.
bash-3.00# grep -n '.*' textfile.txt 
1:This is line 1
2:This is line 2
3:This is line 3
4:This is line 4
5:This is line 5
The RE . (dot) is used to match a single character and the pattern * is used to match zero or more occurences, thus printing all line numbers when used with grep -n.

2. Deleting or Removing all lines in a file which matches a pattern

The grep -v command can be used display lines which DON'T match a pattern or in other words remove lines which matches a pattern in a file.

For example in the above text file, to remove or delete lines which matches the pattern "line 1", the command would be
bash-3.00# grep -v "line 1" textfile.txt 
This is line 2
This is line 3
This is line 4
This is line 5
To delete lines which matches the pattern "line 1" or "line 3", use the egrep command
bash-3.00# egrep -v '(line 1|line 3)' textfile.txt 
This is line 2
This is line 4
This is line 5
3. Deleting the first line which matches a pattern in a file

This is an example which uses the grep command piped to other UNIX commands like sed. To delete only the first line which matches a pattern in a file, use the following grep - sed pipe.

The below command deletes the first line which matches the pattern "line" in the above text file.
bash-3.00# grep "line" textfile.txt | sed 1d
This is line 2
This is line 3
This is line 4
This is line 5
The sed 1d command deletes the first line in the above grep output.

4. Deleting the last line which matches a pattern in a file

To delete the last line which matches a pattern in a file, use the grep - sed command pipe as shown below.

The below command deletes the last line which matches the pattern "line" in the above text file.
bash-3.00# grep "line" textfile.txt | sed '$d'
This is line 1
This is line 2
This is line 3
This is line 4
The sed $d command deletes the last line in the above grep output.

Likewise there are countless applications of grep command piped with other utility commands like awk, sed, etc to match patterns in a file and I will add more as and when I find something interesting.

Polymorphism in Java Arrays

Wednesday, December 24, 2008

When I was preparing for my SCJP 6.0,I was learning many interesting features of java, one such thing was how polymorphism would apply to java arrays as compared to java objects.

For a customary introduction, polymorphism is a OOPS concept which allows a class to hold a reference to an instance of any of its subclasses and invoke methods of different subclass objects to which the reference points to at runtime, in other words this is also called runtime ploymorphism in the sense the object on which the method is invoked is determined at runtime, of course the subclass should override the method which the superclass defines and those are the only methods which can be invoked through the superclass reference to the subclass instance. Ok, enough on polymorphism.

I was discussing how polymorphism would work with arrays with one of my friend (in fact I attribute this entry to him as I learnt this through his fancy questions), the scenario is like this.

1. Declare an array of type baseclass which points to the subclass array object (Polymorphism or polymorphic reference)
2. Assign the first array element of baseclass to the subclass object (Not a great deal of thinking required to tell that its allowed).
3. Assign the second array element of baseclass to the baseclass object.

Now we are interested in how the behavior would be on the assignment in line 3, lets go through the code.

Listing 1: subClass.java

1: /**
 2:  * @(#)subClass.java
 3:  *
 4:  *
 5:  * @author: Prasanna S 
 6:  * @version 1.00 2008/11/25
 7:  */
8:
9: class baseClass {
10:         public baseClass() {    
11:         }
12: }
13:
14: public class subClass extends baseClass {
15:
16:     public subClass() {
17:     }
18:
19:     public static void main (String args[]) {
20: 
21:         // Creating a baseClass Array reference to point to subClass Array object - OK
22:         baseClass baseClassArray [] = new subClass [5];
23: 
24:         // Assigning a baseClass Array element to subClass instance - OK
25:         baseClassArray[0] = new subClass();
26: 
27:         // Assigning a baseClass Array element to baseClass instance 
28:         // Runtime exception - ArrayStoreException
29:         
30:         baseClassArray[1] = new baseClass();
31:     }
32: }
Output and Explanation:

As commented out in the code, the above program will compile successfully, but will throw a runtime exception at line 30 as shown below.

Exception in thread "main" java.lang.ArrayStoreException: baseClass
at subClass.main(subClass.java:30)

There are two classes named baseClass and subClass in the above listing, and in line 22, we create a base class array reference to point to a subclass object array reference.

Line 25 assigns a subClass object to baseClassArray[0] which is acceptable according to polymorphism rules.

Line 30 assigns a baseClass object to baseClassArray[0], which results in ArrayStoreException because you can't have a reference to a baseClass object in an subClass array object NEVER, note that its very easy to get confused and accept that this code would work if one sees the reference type in the left hand side of the assignment.

The lesson: If we try to store a baseClass reference in an object of subClass type, we will get a ClassCastException for java objects as it violates polymorphism principle or IS-A relationship (a subclass IS-A baseclass through inheritance, but not otherwise), but for arrays you will get an ArrayStoreException.

Sun Certified Solaris Associate (SCSAS) - Your first Solaris Certification

Sunday, December 21, 2008

Today I took my first Solaris 10Certification exam Sun Certified Solaris Associate (SCSAS) and cleared it with 86% score, there were 52 questions in it and I got 45 of them right. Even though I have been working in Solaris environment for some years, but I wanted to rate/test myself on my Solaris skills and with little preparation, got a good result, also its not a cake walk either, as always I learn something new with every adventure, so that served the purpose of going for this certification at the first place and spending some time on it.

The Sun Certified Solaris Associate (SCSAS) is the recent Solaris 10 Certification exam introduced by Sun mainly for beginners who want to get a basic knowledge of UNIX environment through Solaris 10, if you are a UNIX newbie, I strongly RECOMMEND this to you as you will get a solid foundation in Solaris/UNIX environments by taking SCSAS and will feel much more confident in working with Solaris or other UNIX Environments.

For intermediate or experienced Solaris Programmers who are keen on pursuing advanced certifications like Sun Certified System Administrator for the Solaris Operating System (SCSA) or Sun Certified Network Administrator for the Solaris Operating System (SCNA) or Sun Certified Security Administrator for the Solaris Operating System (SCSECA), this may be a good warm up to refresh their basic Solaris skills before advancing to further levels, in any case having a certification like this would be handy as one can establish themselves in Solaris with an officially recognized certification like this.

Also for University students, this would be the first place to start with to get some recognition for your UNIX/Solaris skills before getting into the industry, OK lets look at the concepts tested in SCSAS, I have subdivided into five categories.

The Certification Objectives....

1. Understanding Solaris desktop environment, command line, searching man pages, introduction of Korn, Bourne, C Shells and simple system security concepts you need to be aware of.
2. Getting comfortable with file systems, directory manipluation, search commands, vi editor, file/directory permission concepts and Configuring Access Control lists.
3. Understanding UNIX Processes, the commands associated in creating tasks, killing processes and other aspects process handling.
4. Advanced shell functionality, shell metacharacters, shell scripting, customizing your environments on different shells.
5. Archiving techniques and commands for remote file transfer.

Getting hands on in these concepts will always be helpful for any UNIX environments and from my experience, even though I was initially complacent and took a practice test hoping to complete the formalities soon, I was really humbled as this certification requires some preparation no matter how much UNIX experience you may, it will just expose the areas you need to focus as it did it for me, prompting me to learn for a couple of days, tying up some loose ends.

Tips and Suggestions.... Finally my suggestions for those who wanna take this exam would be as follows.

1. If you are a UNIX newbie, give yourself a couple of months and most importantly work in a Solaris 10 environment, try and experiment in your system, get as comfortable as you can, master all the features and objectives of SCSAS so that you WILL never forget those anytime as that's the purpose of doing this certification.

2. If you are an intermediate level Solaris programmer, then this is for you as I mentioned earlier, it will expose the areas you need to focus and improve on, so that you can become a better UNIX programmer.

3. If you call yourself as a Solaris Guru, then it won't hurt to reaffirm that belief through this certification, I am sure some of them might require you to think.

References and Readings Though there were not any official certification material released for this, if you need some reference, any reading on Sun Solaris 10 or Solaris 10 Complete Reference may help, but those might be a little overkill for beginners, I can help with some beginners materials for this through Sun, also Sun is promoting/encouraging Solaris awareness among beginners and university students with many good initiatives, do let me know if you are serious about it.

SCJP Sun Certified Java Programmer 1.6 Tips and Tricks

Saturday, December 13, 2008

This week I took the SCJP Sun Certified Programmer for Java 6 Exam 310-065and cleared it with 73%. The SCJP 1.6 exam is little tricky in that Sun has raised the bar a little to pass the exam, you should get 65% to pass the SCJP 1.6 exam, you will have 72 questions and should answer atleast 65% of them right or atleast 47 right responses.

Ok, why should anyone go for Sun Certified Java Programmer (SCJP) 1.6 exam, the reason varies, if you want to have a career in Java but need a strong foundation then its for you, I took it because I wanted to refresh the latest java features, to master some key OO concepts, assertion mechanisms, object oriented concepts like polymorphism, overloading, inheritance, object serialization, inner classes/nested classes, threading/synchronization, get hands on with new features of java 1.5 and above like Generics, etc, I should say I am quite satisfied with the way it went.

A word of caution though, SCJP 1.6 is not only for beginners of Java programming language but for seasoned Java programmers too, although I knew Java before, but I really learnt a lot from the SCJP 1.6 preparation and you will too realize that once you go through the SCJP 1.6 objectives, it's most likely that it will clear some of the misconceptions may have had in java and will set a firm foundation on Java programming language and its important concepts with its potential use in real world applications.

The following may be some useful tips and tricks for those who are planning to take SCJP 1.6.

1. Reference for SCJP 1.6

The only reading I went through till date for SCJP 1.6 preparation was SCJP Sun Certified Programmer for Java 6 Exam 310-065by Katherine Sierra, Bert Bates, if you grasp the contents in this reading and take the practice tests which includes tricky questions and lucid explanation of answers, you WILL sail through for sure, but make sure that you go through all the chapters even if you are a good java programmer because its likely that you will learn something new in some section of this book, NEVER ignore any sections on reading.

2. Time for preparation

Ideally it will take a month and a half to prepare for the exam including the two practice tests, but if you want to get the best of of the SCJP 1.6, give a couple of months, its not that getting through SCJP which should matter, but its where you take your Java skills through SCJP preparation which really matters, in that case to get the best worth out of it, it may take a couple of months as was the case for me.

3. Key Concepts

The objectives of SCJP 1.6 is to test your skills on Java fundamentals, Object Oriented concepts like polymorphism, overloading, overriding, Generics concepts, Inner classes, Threads and Synchronization, differences between abstract classes & interfaces, packaging, rudimentary concepts like flow control, declarations, etc. However the most important concepts which is likely to stump you would be on sections in

1. Thread Programming and Syncronization
2.
Generics
3. Inner Classes, use of static classes and methods
4. OOPS Concepts like polymorphism
5. Garbage Collection features

One needs to be vary sharp in answering questions in these sections.

Therefore to start with learn simple, fundamental concepts of java like declaration, looping constructs, flow control, etc, then look keenly on the core features of java mentioned above, its likely that every rule you learn on generics, OOPS concepts and other important features of java will be crucial to your success on SCJP 1.6.

4. Practice, Practice, Practice....

Give a months time for going through the contents of the book, learn all chapters page by page, my advice is never give the tests at the end of each chapter till you finish your reading although you may go through the two minute drills in the above reading at the end of each chapter which summarizes the key points for that chapter.

Reserve the second part of the preparation completely on practice tests, go through the individual practice tests at the end of each chapter, learn the key concepts which require additional focus, then take the the sample exams, again the best way to go through the sample exam is to attempt individual questions and then look the answers for them even if they are right or wrong, learning in this way would ensure that you will never forget the key concepts you will be tested on in SCJP 1.6.

Last but not the least repeat your practice tests at the end of the chapter and sample tests, its most likely that you may have some minor mistakes even if you take them twice or more, but the more you learn from mistakes, the stronger you will be on the SCJP 1.6, best of luck!

I will also be blogging on some useful java code and key java concepts for my reference and also for your reading, you will find themselves useful for sure to clear your doubts and learn new concepts, keep visiting :).

Sun Microsystems Education, Project and Career Oppurtunities for Students

Saturday, November 29, 2008

I was often asked by some student friends about the projects they can work on, here I would like to introduce some of the oppurtunities students can explore with Sun Microsystem's brand open source software like Netbeans, Glassfish, OpenSolaris, JavaFX, OpenSPARC, VirtualBox, OpenOffice, Java and MySQL to name a few, the reason why Sun technologies can be a compelling choice for the student community is Sun technologies are available to you free or open source and it has a rich developer community, forums, mailing lists which can always help you.

For a student, Sun Microsystem's open source technologies are a boon to say the least in that they get every thing they need from IDE, Database, Application programming language, the highly secure Solaris Operating system, in short, virtually a complete software stack for free, its extremely important that they explore these technologies at the earlier phases of their academics so that they can reap the full benefits of these technologies which will help them not only in executing successful academic research projects with the latest cutting edge technologies but also end up in lucrative professional careers as well. Here are the step by step approach a student can take as far as exploring these technologies.GetJava Download Button


I am not sure about your specific interests but sky is the limit as far as exploring Sun Microsystems open source technologies are concerned, you can get everything you need to explore completely for FREE with open source to play with, for example if you are interested in hardware design, then openSPARC is for you, interested in exploring the highly scalable and secure operating system? then OpenSolaris is for you, or a programming geek, go with Open Java.

Start with any of the above technologies you are interested in, download them for free, install them, start playing with, you will appreciate these technologies for sure.Innovate on OpenSolaris


Visit the above page, register as a student and get access to all training materials and courses right from learning java, exploring Netbeans, open source, etc absolutely FREE!


Got struck? You can always post your questions by visiting the above page, get advice from experts for solutions to your problems related to these technologies.

Sun has tie ups with leading universities all over the world and has a Campus Ambassador program for student developers, which students can leverage to a greater extent to fulfil their academic objectives as well as career goals, I know that through this program, there are several students mentored by Sun Engineers which resulted in exciting projects, one such example, openSolaris in USB developed in India.
The Events Calendar page updates about the Sun Microsystem's campus events for different universities where one can check the future Sun events in their universities, also look for Sun Microsystems job or internships available for students,where one can kick start their careers with cutting edge technologies with Sun.

For more details about oppurtunities and career options available to students with Sun open source technologies, do contact me, also you can always look for more details in Sun Student Central web page anytime.

Changing Java Webstart Settings: Opening JNLP files with a specific JRE

Friday, November 28, 2008

JNLP (Java Network Launching Protocol) files launched from browser are used to execute Java Webstart applications, the difference between Java Webstart applications and Java applets are Java Webstart applications don't run inside the browser (consider them as a Java application launched through browser which runs on the client machine but not in the browser context), whereas a java applet runs in an web browser context, they are executed in a sandbox with security restrictions and they may not access local data.

Java Webstart applications are lauched by javaws (can be found in JAVA_HOME/bin/javaws).

Java Webstart applications can be used when a software application needs to be run on the client system without browser dependency (which applets require), as obvious Java Webstart applications are platform independent software and can be launched from any platform with the supported JRE for the application (say Java 1.4 or 1.5).

Often we may need to launch a Java Webstart application on a specific JRE, this may be done by changing Java Webstart settings by selectively enabling the specific JRE as default or by specifying the javaws path upon prompted before opening the Java Webstart application, we will specifically see how to run a single java webstart application with two different JREs (JRE Version 1.5 and 1.6).

The sample web application used is a java swing text validation utility which can be found here, use this application to try out both the approaches.

Selectively Enabling Java Application runtime settings:

1. Launch Java Webstart settings (All Programs -> Control Panel -> Java)

2. Click on Java tab -> View button on Java Application Runtime Settings

3. One can see the all the JRE versions installed in that machine, by default all of them would be enabled, see the below figure.


Figure 1: JNLP Runtime settings showing installed JRE versions

4. To enable only a specific JRE to be used to launch applications by default, enable only that specific JRE, for example from the above figure, to select only Java 1.6 runtime to launch your Webstart applications, uncheck Java 1.5 option (see the above figure), click OK, click Apply from the Java Application Runtime Settings section, then restart the browser.

Choosing a specific JRE version for Java Webstart applications on the fly by specifying the javaws path:

One can also specify the path for javaws on the specific JRE installation location to be used to execute Java webstart applications. Before doing this, one needs to enable the prompt user option through the Java Runtime settings before executing a Webstart application .

1. Launch Java Webstart settings (All Programs -> Control Panel -> Java)

2. Click Advanced tab

3. Expand JNLP File/MIME Association, select the Prompt User option, click Apply, restart the browser (see below).


Figure 2: Changing JNLP/MIME Association settings

4. Now whenever you open a JNLP file, you will be prompted with options to open the application either with the default settings or choosing the JRE location (javaws,) if the location of javaws is selected, then that JRE will be used (see the below figure).


Figure 3: Specifying the JRE location (javaws) to open a Java Webstart Application

Mounting CDROM ISO Images in Solaris using lofiadm

Wednesday, November 12, 2008

Many a times we need to mount an ISO Image from CDROM to install a product, in Solaris this process is simplified with the lofiadm command which I used recently to install ISOs and hope this will be a useful reference.

lofiadm is a system administration command in Solaris which allows a file to be associated with a block device which can then be mounted on the local file system.

For example assume that a product is shipped as an ISO Image which needs to be installed, if the ISO file path is /var/tmp/CDImage.iso (say), then the sequence of steps to associate the ISO Image to the block device and mount it to the local file system would be as follows.

1. Remove existing ISO Block device using lofiadm if any

/usr/sbin/lofiadm -d /dev/lofi/1

2. Using lofiadm, associate the CD ISO Image as a block device

/usr/sbin/lofiadm -a /var/tmp/CDImage.iso

3. Mount the CD-ROM block device in the local file system.

/usr/sbin/mount -F hsfs -o ro /dev/lofi/1 /mnt

(Make sure you unmount any existing mounts in /mnt using /usr/sbin/umount /mnt)

Note: In the above mount command the hsfs represents High Seirra file system, a CD-ROM file system for Solaris.

4. cd /mnt to invoke the installer.

(Make sure you cleanup the block device and unmount the /mnt after the installation is complete using /usr/sbin/mount -F hsfs -o ro /dev/lofi/1 /mnt and /usr/sbin/lofiadm -d /dev/lofi/1 respectively).

Self Improvement: The Hidden Secret in Think and Grow Rich

Here I want to share my views about the books I read till date which made some difference to me and are also making a mark among readers with their uniqueness among plethora of writings available these days on virtually every subject, this one is for ambitious persons who want to accomplish their goals but need an organized way of approaching things, in general this book can be regarded as an excellent complimentary for Napoleon hill's inspirational writing "Think and Grow Rich" used by many over decades.

Even though this is a technical blog, but I still see some purpose of putting this here so that readers can benefit out of this in pursuing their endeavors, which may be technical accomplishments too (but not limited to of course).

The reading "The Hidden Secret in Think and Grow Rich" appealed to me because of the following reasons.

1. Short, precise, and concise This book is just about 100 odd pages, so it won't take much to get the crux of the idea.


2. Lucid explanation of the steps Some of the key factors to success which you will find in "Think and Grow Rich" like Desire, Faith, Auto Suggestion, Specialized Knowledge, Imagination, Organized Planning, Decision, Persistence, Master Mind, Transmutation, Subconsious mind, Brian, Sixth sense are connected very well in this writing at the respective chapters and most importantly explains how each step when executed in the correct order would naturally lead to the habit of inculcating the other attributes of success, for example if you have STRONG desire, faith and organized plan, you will naturally be persistent, etc.

3. Practical and Logical steps I came through this e-book when I was recommended by one of my friend on the article "How to find what you love to do", if you love that reading you would appreciate "The Hidden Secret in Think and Grow Rich" for sure because this is not a mere book, but also has practical exercises which one should follow in order to realize their dreams (like you should take notes whenever some idea strikes, always write, to-do lists, how to break a huge task into reasonable small chunks, etc).

4. It will work.. How far is up to the desire of the individuals but if you have a strong desire to get the best of this book for your self improvement or accomplishing your mission, then you will get more than the value of your money for sure.

5. Examples, inspirational success stories, etc Though you are strongly advised to go through Napoleon Hill's "Think and Grow Rich" before proceeding this one, you can still grasp the examples in this book even otherwise. Most of the stories were examples of how organized execution would lead to accomplishment of your mission with inspiring stories of great persons over the centuries, which in turn would fuel the fire in your belly to accomplish your goals.

6. Supplementary workbooks and reports You would also get a free "The Hidden Secret Workbook" and a report "The Three Biggest Mistakes People Make With The Hidden Secret" with these you can evaluate your strengths, how you can use them to work for you and avoiding common pitfalls which you might make in setting your goals, also you would get a free electronic copy of "Think and Grow Rich".

Even though I am skeptical of too much examples, success stories, motivational and self improvement books, after reading this that perception changed quite a lot as this has very practical and proven ways to get where you want, also I recommend you to go through the self improvement articles of Brian which would make interesting and refreshing readings.

Implementing a simple HTTP Server in java for handling POST methods: A File Upload HTTP Server

Sunday, November 2, 2008

Note: An updated version of this post can be found in http://www.prasannatech.net/2009/03/java-http-post-file-upload-server.html which will handle any kind of file uploads (text and binary files) of large size.

In the last section on java, we have seen how to implement a simple/lightweight HTTP/Web Server to handle HTTP GET methods. In this section, we will see how to implement a simple HTTP/Web server in java to handle POST methods with an example of a file upload server using the POST method through a client form data.

The benefit of implementing our own HTTP Server to handle GET/POST methods is that we can use them for some simple/lightweight applications which doesn't require an Apache Web server or a servlet container to be deployed to handle HTTP client requests, also these simple HTTP servers can be used as utility classes which can be integrated in a small scale applications.

The below HTTP POST Server does the following functions.

1. Displays the File upload form when the home page is accessed (http://127.0.0.1:5000), displays error for other invalid GET requests.

2. Uploads a text file through the file upload form and submit it, the end result is that the file will be uploaded in the directory where the HTTPPOSTServer class runs, Note: This code will work only for text files.

3. Handles text files upto 2MB.

I have tested the code in IE 7, Firefox and Chrome (BTW I needed to change the code a lot to make it IE compatible). The lesson learned, always test your code in IE first to avoid disappointments as its likely to give you some tough time the other way around (nothing against IE though).

So here's the code.

Listing 1: HTTPPOSTServer.java

  1 /*
2 * HTTPPOSTServer.java
3 * Author: S.Prasanna
4 * @version 1.00
5 */
6
7 import java.io.*;
8 import java.net.*;
9 import java.util.*;
10
11 public class HTTPPOSTServer extends Thread {
12
13 static final String HTML_START =
14 "<html>" +
15 "<title>HTTP POST Server in java</title>" +
16 "<body>";
17
18 static final String HTML_END =
19 "</body>" +
20 "</html>";
21
22 Socket connectedClient = null;
23 BufferedReader inFromClient = null;
24 DataOutputStream outToClient = null;
25
26
27 public HTTPPOSTServer(Socket client) {
28 connectedClient = client;
29 }
30
31 public void run() {
32
33 String currentLine = null, postBoundary = null, contentength = null, filename = null, contentLength = null;
34 PrintWriter fout = null;
35
36 try {
37
38 System.out.println( "The Client "+
39 connectedClient.getInetAddress() + ":" + connectedClient.getPort() + " is connected");
40
41 inFromClient = new BufferedReader(new InputStreamReader (connectedClient.getInputStream()));
42 outToClient = new DataOutputStream(connectedClient.getOutputStream());
43
44 currentLine = inFromClient.readLine();
45 String headerLine = currentLine;
46 StringTokenizer tokenizer = new StringTokenizer(headerLine);
47 String httpMethod = tokenizer.nextToken();
48 String httpQueryString = tokenizer.nextToken();
49
50 System.out.println(currentLine);
51
52 if (httpMethod.equals("GET")) {
53 System.out.println("GET request");
54 if (httpQueryString.equals("/")) {
55 // The default home page
56 String responseString = HTTPPOSTServer.HTML_START +
57 "<form action=\"http://127.0.0.1:5000\" enctype=\"multipart/form-data\"" +
58 "method=\"post\">" +
59 "Enter the name of the File <input name=\"file\" type=\"file\"><br>" +
60 "<input value=\"Upload\" type=\"submit\"></form>" +
61 "Upload only text files." +
62 HTTPPOSTServer.HTML_END;
63 sendResponse(200, responseString , false);
64 } else {
65 sendResponse(404, "<b>The Requested resource not found ...." +
66 "Usage: http://127.0.0.1:5000</b>", false);
67 }
68 }
69 else { //POST request
70 System.out.println("POST request");
71 do {
72 currentLine = inFromClient.readLine();
73
74 if (currentLine.indexOf("Content-Type: multipart/form-data") != -1) {
75 String boundary = currentLine.split("boundary=")[1];
76 // The POST boundary
77
78 while (true) {
79 currentLine = inFromClient.readLine();
80 if (currentLine.indexOf("Content-Length:") != -1) {
81 contentLength = currentLine.split(" ")[1];
82 System.out.println("Content Length = " + contentLength);
83 break;
84 }
85 }
86
87 //Content length should be < 2MB
88 if (Long.valueOf(contentLength) > 2000000L) {
89 sendResponse(200, "File size should be < 2MB", false);
90 }
91
92 while (true) {
93 currentLine = inFromClient.readLine();
94 if (currentLine.indexOf("--" + boundary) != -1) {
95 filename = inFromClient.readLine().split("filename=")[1].replaceAll("\"", "");
96 String [] filelist = filename.split("\\" + System.getProperty("file.separator"));
97 filename = filelist[filelist.length - 1];
98 System.out.println("File to be uploaded = " + filename);
99 break;
100 }
101 }
102
103 String fileContentType = inFromClient.readLine().split(" ")[1];
104 System.out.println("File content type = " + fileContentType);
105
106 inFromClient.readLine(); //assert(inFromClient.readLine().equals("")) : "Expected line in POST request is "" ";
107
108 fout = new PrintWriter(filename);
109 String prevLine = inFromClient.readLine();
110 currentLine = inFromClient.readLine();
111
112 //Here we upload the actual file contents
113 while (true) {
114 if (currentLine.equals("--" + boundary + "--")) {
115 fout.print(prevLine);
116 break;
117 }
118 else {
119 fout.println(prevLine);
120 }
121 prevLine = currentLine;
122 currentLine = inFromClient.readLine();
123 }
124
125 sendResponse(200, "File " + filename + " Uploaded..", false);
126 fout.close();
127 } //if
128 }while (inFromClient.ready()); //End of do-while
129 }//else
130 } catch (Exception e) {
131 e.printStackTrace();
132 }
133 }
134
135 public void sendResponse (int statusCode, String responseString, boolean isFile) throws Exception {
136
137 String statusLine = null;
138 String serverdetails = "Server: Java HTTPServer";
139 String contentLengthLine = null;
140 String fileName = null;
141 String contentTypeLine = "Content-Type: text/html" + "\r\n";
142 FileInputStream fin = null;
143
144 if (statusCode == 200)
145 statusLine = "HTTP/1.1 200 OK" + "\r\n";
146 else
147 statusLine = "HTTP/1.1 404 Not Found" + "\r\n";
148
149 if (isFile) {
150 fileName = responseString;
151 fin = new FileInputStream(fileName);
152 contentLengthLine = "Content-Length: " + Integer.toString(fin.available()) + "\r\n";
153 if (!fileName.endsWith(".htm") && !fileName.endsWith(".html"))
154 contentTypeLine = "Content-Type: \r\n";
155 }
156 else {
157 responseString = HTTPPOSTServer.HTML_START + responseString + HTTPPOSTServer.HTML_END;
158 contentLengthLine = "Content-Length: " + responseString.length() + "\r\n";
159 }
160
161 outToClient.writeBytes(statusLine);
162 outToClient.writeBytes(serverdetails);
163 outToClient.writeBytes(contentTypeLine);
164 outToClient.writeBytes(contentLengthLine);
165 outToClient.writeBytes("Connection: close\r\n");
166 outToClient.writeBytes("\r\n");
167
168 if (isFile) sendFile(fin, outToClient);
169 else outToClient.writeBytes(responseString);
170
171 outToClient.close();
172 }
173
174 public void sendFile (FileInputStream fin, DataOutputStream out) throws Exception {
175 byte[] buffer = new byte[1024] ;
176 int bytesRead;
177
178 while ((bytesRead = fin.read(buffer)) != -1 ) {
179 out.write(buffer, 0, bytesRead);
180 }
181 fin.close();
182 }
183
184 public static void main (String args[]) throws Exception {
185
186 ServerSocket Server = new ServerSocket (5000, 10, InetAddress.getByName("127.0.0.1"));
187 System.out.println ("HTTP Server Waiting for client on port 5000");
188
189 while(true) {
190 Socket connected = Server.accept();
191 (new HTTPPOSTServer(connected)).start();
192 }
193 }
194 }
195

Working:

The working of the code is pretty simple, the HTTP server checks for a GET or POST method, and if its a GET method (line 53) for the home page, it displays the file upload form through which the user can upload the file, in case of any other invalid GET requests other than home page, an error message is displayed (line 65).

Line 70 handles POST request and checks the content type (line 74), POST boundary (line 75), content length (line 81) and the file name (line 98), once these values are parsed, the file is uploaded successfully (lines 108 - 126) provided the file length is 88).

I have commented out some assertions which should be true when parsing the POST request string, but then the code will only work when assertions were enabled (using java -ea HTTPPOSTServer), which in general is not a good practice, therefore if you want to learn more about how HTTP POST requests, add your own assertions while parsing the POST request when you expect something in the request line which should match a particular string.


Copyright © 2016 Prasanna Seshadri, www.prasannatech.net, All Rights Reserved.
No part of the content or this site may be reproduced without prior written permission of the author.