PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/ws-main.pl

http://my-perl-webservice.googlecode.com/
Perl | 163 lines | 116 code | 33 blank | 14 comment | 13 complexity | 4c2fd00865911d7c3c3bcd68288f7a60 MD5 | raw file
  1. #!/usr/bin/perl
  2. ### Standart modules
  3. use strict;
  4. use warnings;
  5. use IO::Socket;
  6. use Getopt::Long; ### This module handles command line argiments reading
  7. ### 3rd party modules
  8. ### Project specific modules
  9. use logger;
  10. ##############################################################################
  11. initialize_logging("/tmp/my-perl-webservice/");
  12. my $host = '0.0.0.0';
  13. my $port = 8080;
  14. my $help = 0;
  15. GetOptions(
  16. 'h|help' => \$help,
  17. 'port|p:i' => \$port,
  18. 'loglvl|log:s' => \$LOG_LVL );
  19. if( $help == 1 )
  20. {
  21. print_usage_notes();
  22. exit 0;
  23. }
  24. ### Start Working
  25. my $sock = new_listener($host, $port) or die "Can't create server: $!";
  26. my $c; #connection
  27. $SIG{CHLD} = 'IGNORE'; # Don't reap zombies
  28. msg("Entering accept loop (port $port)");
  29. while (1)
  30. {
  31. #parent = listener
  32. dbg("Waiting for connections");
  33. $c = $sock->accept;
  34. dbg("Accepted connection");
  35. if (!defined $c)
  36. {
  37. dbg("Accept timeout. Retrying");
  38. next;
  39. }
  40. msg("Forking off child to handle connection");
  41. my $pid = fork;
  42. if( $pid == 0 )
  43. {
  44. last; # last will happen to child, parent stays in loop
  45. }
  46. dbg("New connection handler forked. Pid=$pid");
  47. }
  48. ### Child handles a connection
  49. undef $sock; # close listening socket
  50. #Hello message
  51. #send_data( $c, "Hello message\n" );
  52. my $cmdrecv = "";
  53. while (1)
  54. {
  55. #child handles all commands
  56. $cmdrecv = "";
  57. msg("Start listening for command");
  58. $c->recv( $cmdrecv, 65536 );
  59. msg("Command received.");
  60. dbg("---------------");
  61. dbg($cmdrecv);
  62. dbg("Size: ".length($cmdrecv));
  63. dbg("hex: ".unpack('H*', "$cmdrecv"));
  64. dbg("---------------");
  65. if( $cmdrecv eq '' || $cmdrecv eq "\r\n" || $cmdrecv eq "\n\r" || $cmdrecv eq "\n" )
  66. {
  67. msg("Client Closed!");
  68. msg("Shutting down connection");
  69. shutdown( $c, 2 );
  70. $c->close;
  71. msg("Done");
  72. exit;
  73. }
  74. else
  75. {
  76. ###This is a real request.
  77. ###Form response chunks
  78. my $response_text = form_http_response("This is a simple response");
  79. msg("Sending response data");
  80. send_data( $c, $response_text );
  81. }
  82. }
  83. sub form_http_response
  84. {
  85. my ($data) = @_;
  86. return
  87. "HTTP/1.1 200 OK\r\n".
  88. "Connection: close\r\n".
  89. "Content-Length: ".length($data).
  90. "\r\n\r\n".
  91. $data;
  92. }
  93. sub send_data
  94. {
  95. my ($c, $data) = @_;
  96. dbg( "Sending ".length($data)." bytes: ".$data );
  97. $c->print($data);
  98. $c->flush;
  99. }
  100. sub new_listener
  101. {
  102. my ($host, $port) = @_;
  103. my $s = IO::Socket::INET->new(
  104. LocalAddr => $host,
  105. LocalPort => $port,
  106. Proto => 'tcp',
  107. ReuseAddr => 'true',
  108. Listen => 5,
  109. Timeout => 10)
  110. or return undef;
  111. $s->sockopt(SO_REUSEADDR => 1);
  112. $s->autoflush(1);
  113. return $s;
  114. }
  115. sub print_usage_notes
  116. {
  117. print( "Usage:
  118. $0 [--port|-p <LISTENING PORT>] [--loglvl|-log <LOGGING LEVEL>] [--help|-h]\n
  119. Parameters notes:
  120. --port, -p [Default=9000] The listening port.
  121. --loglvl, -log [Default=4] The logging level.
  122. 0 - Suppress all logging.
  123. 1 - Errors only,
  124. 2 - Messages and errors only,
  125. 3 - Debugging messages, messages and errors,
  126. 4(and above) - Add log dump to stdout.
  127. --help, -h print this usage and exit.\n" );
  128. }
  129. #EOF