/*
* Created on Feb 15, 2007
* Created by Paul Gardner
* Copyright (C) 2007 Aelitis, 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; either version 2
* of the License, or (at your option) any later version.
* 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.
*
* AELITIS, SAS au capital de 63.529,40 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
package com.aelitis.azureus.core.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class HTTPUtils {
public static final String NL = "\r\n";
private static final String default_type = "application/octet-stream";
private static final Map file_types = new HashMap();
private static final Set compression = new HashSet();
static {
file_types.put("html", "text/html");
file_types.put("htm", "text/html");
file_types.put("css", "text/css");
file_types.put("js", "text/javascript");
file_types.put("xml", "text/xml");
file_types.put("xsl", "text/xml");
file_types.put("jpg", "image/jpeg");
file_types.put("jpeg", "image/jpeg");
file_types.put("gif", "image/gif");
file_types.put("tiff", "image/tiff");
file_types.put("bmp", "image/bmp");
file_types.put("png", "image/png");
file_types.put("torrent", "application/x-bittorrent");
file_types.put("tor", "application/x-bittorrent");
file_types.put("zip", "application/zip");
file_types.put("txt", "text/plain");
file_types.put("jar", "application/java-archive");
file_types.put("jnlp", "application/x-java-jnlp-file");
file_types.put("mp3", "audio/x-mpeg");
file_types.put("flv", "video/x-flv");
file_types.put("swf", "application/x-shockwave-flash");
file_types.put("mkv", "video/x-matroska");
file_types.put("mp4", "video/mp4");
file_types.put("mov", "video/quicktime");
file_types.put("avi", "video/avi");
compression.add("text/html");
compression.add("text/css");
compression.add("text/xml");
compression.add("text/plain");
compression.add("text/javascript");
}
/**
* @param file_type file extension
* @return apropriate content type string if found
*/
public static String guessContentTypeFromFileType(String file_type) {
if (file_type != null) {
String type = (String) file_types.get(file_type.toLowerCase());
if (type != null) {
return (type);
}
}
return (default_type);
}
public static boolean
canGZIP(
String accept_encoding )
{
boolean gzip_reply = false;
if ( accept_encoding != null ){
accept_encoding = accept_encoding.toLowerCase();
int gzip_index = accept_encoding.indexOf( "gzip" );
if ( gzip_index != -1 ){
gzip_reply = true;
if ( accept_encoding.length() - gzip_index >= 8 ){
// gzip;q=0
// look to see if there's a q=0 (or 0.0) disabling gzip
char[] chars = accept_encoding.toCharArray();
boolean q_value = false;
for (int i=gzip_index+4;i<chars.length;i++){
char c = chars[i];
if ( c == ',' ){
break;
}else if ( c == '=' ){
q_value = true;
gzip_reply = false;
}else{
if ( q_value ){
if ( c != ' ' && c != '0' && c != '.' ){
gzip_reply = true;
break;
}
}
}
}
}
}
}
return( gzip_reply );
}
/**
* @param file_type a file type like text/plain
* @return true if the file_type should be compressed
*/
public static boolean useCompressionForFileType(String file_type) {
return compression.contains(file_type);
}
public static InputStream decodeChunkedEncoding(InputStream is)
throws IOException {
String reply_header = "";
while (true) {
byte[] buffer = new byte[1];
if (is.read(buffer) <= 0) {
throw (new IOException("Premature end of input stream"));
}
reply_header += (char) buffer[0];
if (reply_header.endsWith(NL + NL)) {
break;
}
}
int p1 = reply_header.indexOf(NL);
String first_line = reply_header.substring(0, p1).trim();
if (first_line.indexOf("200") == -1) {
throw (new IOException("HTTP request failed:" + first_line));
}
String lc_reply_header = reply_header.toLowerCase();
int te_pos = lc_reply_header.indexOf("transfer-encoding");
if (te_pos != -1) {
String property = lc_reply_header.substring(te_pos);
property = property.substring(property.indexOf(':') + 1,
property.indexOf(NL)).trim();
if (property.equals("chunked")) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String chunk = "";
int total_length = 0;
while (true) {
int x = is.read();
if (x == -1) {
break;
}
chunk += (char) x;
// second time around the chunk will be prefixed with NL
// from end of previous
// so make sure we ignore this
if (chunk.endsWith(NL) && chunk.length() > 2) {
int semi_pos = chunk.indexOf(';');
if (semi_pos != -1) {
chunk = chunk.substring(0, semi_pos);
}
chunk = chunk.trim();
int chunk_length = Integer.parseInt(chunk, 16);
if (chunk_length <= 0) {
break;
}
total_length += chunk_length;
if (total_length > 1024 * 1024) {
throw (new IOException("Chunk size " + chunk_length
+ " too large"));
}
byte[] buffer = new byte[chunk_length];
int buffer_pos = 0;
int rem = chunk_length;
while (rem > 0) {
int len = is.read(buffer, buffer_pos, rem);
if (len <= 0) {
throw (new IOException(
"Premature end of stream"));
}
buffer_pos += len;
rem -= len;
}
baos.write(buffer);
chunk = "";
}
}
return (new ByteArrayInputStream(baos.toByteArray()));
}
}
return (is);
}
}