Package com.aelitis.azureus.core.devices.impl

Source Code of com.aelitis.azureus.core.devices.impl.TranscodePipeFileSource

/*
* Created on Feb 9, 2009
* Created by Paul Gardner
*
* Copyright 2009 Vuze, Inc.  All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/


package com.aelitis.azureus.core.devices.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.util.*;

public class
TranscodePipeFileSource
  extends TranscodePipe
{
  private static final String NL = "\r\n";
 
  private File    source_file;
 
  private RandomAccessFile  raf;
  private int          raf_count;
   
  protected
  TranscodePipeFileSource(
    File      _source_file,
    errorListener  _error_listener )
 
    throws IOException
  {
    super( _error_listener );
   
    source_file  = _source_file;
  }   

 
  protected void
  handleSocket(
    Socket    socket )
  {
    synchronized( this ){
     
      if ( destroyed ){
       
        try{
          socket.close();
         
        }catch( Throwable e ){       
        }
       
        return;
      }
     
      sockets.add( socket );
    }

    try{
      String  command  = null;
      Map<String,String>    headers  = new HashMap<String, String>();

      InputStream    is = socket.getInputStream();
      OutputStream  os = socket.getOutputStream();
     
      while( true ){

        String  line = "";
     
        while( !line.endsWith( NL )){
         
          byte[]  buffer = new byte[1];
         
          is.read( buffer );
         
          line += new String( buffer );
        }
     
        line = line.trim();
       
        if ( line.length() == 0 ){
         
          break;
        }
       
        if ( command == null ){
         
          command  = line;
         
        }else{
         
          int  pos = line.indexOf(':');
         
          if ( pos == -1 ){
           
            return;
          }
         
          String  lhs = line.substring(0,pos).trim().toLowerCase();
          String  rhs = line.substring(pos+1).trim();
         
          headers.put( lhs, rhs );
        }
      }
           
      boolean  head  = false;
     
      //System.out.println( command + ": " + headers );
     
      if ( command.startsWith( "GET " )){
       
      }else if ( command.startsWith( "HEAD " )){
               
        head  = true;
       
      }else{
       
        throw( new IOException( "unsupported method '" + command + "'" ));
      }
     
      long  file_length = source_file.length();
           
      if ( head ){
             
        write( os, "HTTP/1.1 200 OK" + NL );
        write( os, "Server: Azureus Media Server 1.0" + NL );
        write( os, "Accept-Ranges: bytes" + NL );
        write( os, "Content-Length: " + file_length + NL );
        write( os, "Content-Range: 0-" + (file_length-1) + "/" + file_length + NL );

        os.flush();

      }else{
       
        String  ranges = (String)headers.get( "range" );
         
        long  request_start    = 0;
        long  request_length    = 0;
       
        boolean  request_ok = false;
       
        if ( ranges == null ){
                   
          write( os, "HTTP/1.1 200 OK" + NL );
          write( os, "Server: Azureus Media Server 1.0" + NL );
          write( os, "Connection: close" + NL );
          write( os, "Accept-Ranges: bytes" + NL );
          write( os, "Content-Range: 0-" + (file_length-1) + "/" + file_length + NL );
          write( os, "Content-Length: " + file_length + NL + NL );
         
          request_length  = file_length;
         
          request_ok = true;
         
        }else{
                   
          ranges = ranges.toLowerCase();
         
          if ( !ranges.startsWith("bytes=")){
           
            throw( new IOException( "invalid range: " + ranges ));
          }
         
          ranges = ranges.substring( 6 );
         
          StringTokenizer  tok = new StringTokenizer( ranges, "," );
         
          if ( tok.countTokens() != 1 ){
           
            throw( new IOException( "invalid range - only single supported: " + ranges ));
          }
         
          String  range = tok.nextToken();
         
          int pos  = range.indexOf('-');
         
          long  start;
          long  end;
                                 
          if ( pos < range.length()-1 ){
           
            end = Long.parseLong( range.substring(pos+1));
           
          }else{
           
            end = file_length-1;
          }
         
          if ( pos > 0 ){
           
            start = Long.parseLong( range.substring(0,pos));
           
          }else{
              // -500 = last 500 bytes of file
           
            start   = file_length-end;
            end    = file_length-1;
          }
 
          request_length = ( end - start ) + 1;
         
            // prevent seeking too far
         
          if ( request_length < 0 ){
           
            write( os, "HTTP/1.1 416 Requested Range Not Satisfiable" + NL + NL );
           
          }else{   
             
            request_start  = start;
           
            writeos, "HTTP/1.1 206 Partial content" + NL );
             
               
            writeos, "Server: Azureus Media Server 1.0" + NL );
            writeos, "Connection: close" + NL );         
            writeos, "Content-Range: bytes " + start + "-" + end + "/" + file_length + NL );
            writeos, "Content-Length: " + request_length + NL + NL );
           
            request_ok = true;
          }
        }
         
        os.flush();

        if ( request_ok ){
       
          handleRAF( os, request_start, request_length );
        }
      }
     
      synchronized( this ){

        if ( destroyed ){
         
          try{
            socket.close();
           
          }catch( Throwable e ){       
          }
         
          try{
            is.close();
           
          }catch( Throwable e ){       
          }
         
          sockets.remove( socket );
         
          return;
        }
      }     
    }catch( Throwable e ){
     
      try{
        socket.close();
       
      }catch( Throwable f ){
      }
     
      synchronized( this ){

        sockets.remove( socket );
      }
    }
  }
 
  protected void
  write(
    OutputStream  os,
    String      str )
 
    throws IOException
  {
    os.write( str.getBytes());
  }
 
  @Override
  protected RandomAccessFile
  reserveRAF()
 
    throws IOException
  {
    synchronized( this ){
     
      if ( destroyed ){
       
        throw( new IOException( "destroyed" ));
      }
     
      if ( raf == null ){
           
        raf = new RandomAccessFile( source_file, "r" );
      }
     
      raf_count++;
     
      return( raf );
    }
  }
 
  @Override
  protected void
  releaseRAF(
    RandomAccessFile  _raf )
  {
    synchronized( this ){

      raf_count--;
     
      if ( raf_count == 0 ){
       
        try{
          raf.close();
         
        }catch( Throwable e ){
        }
       
        raf = null;
      }
    }
  }
 
  protected boolean
  destroy()
  {
    if ( super.destroy()){
     
      if ( raf != null ){ 
       
        try{       
          raf.close();
         
        }catch( Throwable e ){ 
        }
       
        raf = null;
      }
         
      return( true );
    }
   
    return( false );
  }
}
TOP

Related Classes of com.aelitis.azureus.core.devices.impl.TranscodePipeFileSource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.