перехват загрузки http файлов по протоколу TCP / IP - PullRequest
2 голосов
/ 13 февраля 2011

Я написал один прокси для перехвата запросов http для моего кота.

каждый запрос будет проходить через мой прокси и выполнять некоторую проверку, прежде чем он попадет на сервер Tomcat. я делаю это, привязывая порт с помощью TCP / IP, написанного на Java.

Все запросы (GET и POST) могут успешно перенаправляться на сервер tomcat, кроме отправки файлов (многочастная форма POST).

, хотя я могу получить все байты в TCP / IP и передать данные обратно на сервер Tomcat, каким-то образом данные усекаются / теряются

Есть ли какие-то особые вещи, как кодирование и т. Д., Которые мне нужно делать при работе с содержимым файлового потока ??

ниже мой пример кода ...


protected void processData(InputStream input, OutputStream output) throws IOException
    {
        // reads a line of text from an InputStream
        StringBuffer data = new StringBuffer("");
        StringBuffer data2 = new StringBuffer("");
        StringBuffer data3 = new StringBuffer("");
        StringBuffer data4 = new StringBuffer("");
        int c;

        try
        {
            while ((c = input.read()) >= 0)
            {
                data.append((char) c);

                // check for an end-of-line character
                if ((c == 0) || (c == 10) || (c == 13))
                {
                    output.write(data.toString().getBytes(), 0, data.length());
                    data4.append(data.toString());
                    data = new StringBuffer();
                    count = 0;
                }
                else
                {
                    if (count > 6)
                    {
                        if (input.available() == 1)
                        {
                            data.append((char) input.read());
                        }
                        data2.append(data.toString());
                        data4.append(data.toString());
                        output.write(data.toString().getBytes(), 0, data
                            .toString().length());
                        data = new StringBuffer();
                    }
                    else
                    {
                        if (count == 6)
                        {
                            if (data.toString().toLowerCase()
                                .indexOf("get /") == 0
                                || data.toString().toLowerCase()
                                    .indexOf("post /") == 0)
                            {
                                count = 0;
                                contentLength = -1;

                                // continue read data(header info)
                                while ((line = readLine(input, data)) != null)
                                {
                                    data = new StringBuffer();

                                // do my own stuff here dealing with headers

                                    if (StringUtils.isBlank(line))
                                    {
data4.append(line);
                                        output.write(line.getBytes(), 0,
                                            line.length());

                                        break;
                                    }

                                    line += "\r\n";
                                    output.write(line.getBytes(), 0,
                                        line.length());
                                    data4.append(line);
                                    output.flush();

                                }
                            }
                            else
                            {
                                if (input.available() == 1)
                                {
                                    data.append((char) input.read());
                                }
                            }
                        }
                        else
                        {
                            if (input.available() == 1)
                            {
                                data.append((char) input.read());
                                output.write(data.toString().getBytes(), 0,
                                    data.toString().length());
                                data4.append(data.toString());
                                data3.append(data.toString());
                                data = new StringBuffer();
                            }
                        }
                    }
                    count++;
                }
                if (processbody)
                    total++;

                if (contentLength > 0 && contentLength == total)
                {
                    log.debug("post data2: "
                        + (data2.toString() != null ? data2.toString() : " "));
                    log.debug("post data3: "
                        + (data3.toString() != null ? data3.toString() : " "));
                    log.debug("post data4: "
                        + (data4.toString() != null ? data4.toString() : " "));
                    output.flush();
                }
            }
        }
        catch (Exception e)
        {
            log.error("Error ", e);
        }
        finally
        {
        }
    }


Ответы [ 2 ]

1 голос
/ 14 февраля 2011

В вашем коде есть несколько недостатков:

  1. Вы читаете каждый byte из InputStream, а затем преобразуете его в char и добавляете его в построитель строк. Если поток кодируется символами, например, китайский, греческий, любые специальные символы, это не сможет правильно декодировать поток в читаемую строку. Или, если поток является чисто двоичным или ascii, строка не является лучшим для хранения вашего потока. Это может легко произойти, если вы отправите файл из нескольких запросов.

  2. Я не эксперт по параллелизму (поэтому я мог бы сказать, что здесь нет смысла), но что произойдет, если одновременно будет происходить более одного соединения. Вы должны быть осторожны об этом.

Из того, что я вижу, вы хотите разобраться с заголовком http-запроса, поэтому нет причин, по которым вам не следует использовать фильтр сервлетов, как предложил Алексей Свиридов. Вы можете реализовать свой собственный фильтр, чтобы перехватывать заголовок и что-то с ним делать. Преимущество использования фильтра заключается в том, что вы можете позволить сервлетному API анализировать запрошенный для вас заголовок, и вам не нужно будет беспокоиться о том, когда читать / записывать поток ввода / вывода.

Однако, если вы намереваетесь перехватить заголовок запроса и решить, должен ли запрос быть передан вашему контейнеру tomcat или сервлета, или делать что-то, что не входит в сферу возможностей сервлета, вам следует обратиться к прокси-серверу http библиотеки. Вот пример:

http://proxies.xhaus.com/java/

Предыдущий вопрос о записи HTTP-прокси в Java при переполнении стека.

К сожалению, я не хочу призывать вас написать свой собственный http прокси. Есть слишком много проблем, которые вы должны принять во внимание.

1 голос
/ 14 февраля 2011

Вы делаете это очень трудным путем. Просто прочитайте байты и запишите их на другую сторону. Вам не нужны строки, строковые буферы или символы завершения строки.

...