/** Invoked by the HTTPClient. */
  public int requestHandler(Request req, Response[] resp) throws ModuleException {
    // parse Accept-Encoding header

    int idx;
    NVPair[] hdrs = req.getHeaders();
    for (idx = 0; idx < hdrs.length; idx++)
      if (hdrs[idx].getName().equalsIgnoreCase("Accept-Encoding")) break;

    Vector pae;
    if (idx == hdrs.length) {
      hdrs = Util.resizeArray(hdrs, idx + 1);
      req.setHeaders(hdrs);
      pae = new Vector();
    } else {
      try {
        pae = Util.parseHeader(hdrs[idx].getValue());
      } catch (ParseException pe) {
        throw new ModuleException(pe.toString());
      }
    }

    // done if "*;q=1.0" present

    HttpHeaderElement all = Util.getElement(pae, "*");
    if (all != null) {
      NVPair[] params = all.getParams();
      for (idx = 0; idx < params.length; idx++)
        if (params[idx].getName().equalsIgnoreCase("q")) break;

      if (idx == params.length) // no qvalue, i.e. q=1.0
      return REQ_CONTINUE;

      if (params[idx].getValue() == null || params[idx].getValue().length() == 0)
        throw new ModuleException("Invalid q value for \"*\" in " + "Accept-Encoding header: ");

      try {
        if (Float.valueOf(params[idx].getValue()).floatValue() > 0.) return REQ_CONTINUE;
      } catch (NumberFormatException nfe) {
        throw new ModuleException(
            "Invalid q value for \"*\" in " + "Accept-Encoding header: " + nfe.getMessage());
      }
    }

    // Add gzip, deflate and compress tokens to the Accept-Encoding header

    if (!pae.contains(new HttpHeaderElement("deflate")))
      pae.addElement(new HttpHeaderElement("deflate"));
    if (!pae.contains(new HttpHeaderElement("gzip"))) pae.addElement(new HttpHeaderElement("gzip"));
    if (!pae.contains(new HttpHeaderElement("x-gzip")))
      pae.addElement(new HttpHeaderElement("x-gzip"));
    if (!pae.contains(new HttpHeaderElement("compress")))
      pae.addElement(new HttpHeaderElement("compress"));
    if (!pae.contains(new HttpHeaderElement("x-compress")))
      pae.addElement(new HttpHeaderElement("x-compress"));

    hdrs[idx] = new NVPair("Accept-Encoding", Util.assembleHeader(pae));

    return REQ_CONTINUE;
  }
Beispiel #2
0
  /**
   * Add a token to the given header. If the header does not exist then create it with the given
   * token.
   *
   * @param req the request who's headers are to be modified
   * @param hdr the name of the header to add the token to (or to create)
   * @param tok the token to add
   * @exception ParseException if parsing the header fails
   */
  private void addToken(Request req, String hdr, String tok) throws ParseException {
    int idx;
    NVPair[] hdrs = req.getHeaders();
    for (idx = 0; idx < hdrs.length; idx++) {
      if (hdrs[idx].getName().equalsIgnoreCase(hdr)) break;
    }

    if (idx == hdrs.length) // no such header, so add one
    {
      hdrs = Util.resizeArray(hdrs, idx + 1);
      hdrs[idx] = new NVPair(hdr, tok);
      req.setHeaders(hdrs);
    } else // header exists, so add token
    {
      if (!Util.hasToken(hdrs[idx].getValue(), tok))
        hdrs[idx] = new NVPair(hdr, hdrs[idx].getValue() + ", " + tok);
    }
  }
  /**
   * Closes the stream and causes the data to be sent if it has not already been done so. This
   * method <strong>must</strong> be invoked when all data has been written.
   *
   * @exception IOException if any exception is thrown by the underlying socket, or if too few bytes
   *     were written.
   * @exception IllegalAccessError if this stream has not been associated with a request yet.
   */
  public synchronized void close() throws IOException, IllegalAccessError {
    if (req == null) throw new IllegalAccessError("Stream not associated with a request");

    if (ignore) return;

    if (bos != null) {
      req.setData(bos.toByteArray());
      req.setStream(null);

      if (trailers.length > 0) {
        NVPair[] hdrs = req.getHeaders();

        // remove any Trailer header field

        int len = hdrs.length;
        for (int idx = 0; idx < len; idx++) {
          if (hdrs[idx].getName().equalsIgnoreCase("Trailer")) {
            System.arraycopy(hdrs, idx + 1, hdrs, idx, len - idx - 1);
            len--;
          }
        }

        // add the trailers to the headers

        hdrs = Util.resizeArray(hdrs, len + trailers.length);
        System.arraycopy(trailers, 0, hdrs, len, trailers.length);

        req.setHeaders(hdrs);
      }

      if (DebugConn) System.err.println("OutS:  Sending request");

      try {
        resp = req.getConnection().sendRequest(req, con_to);
      } catch (ModuleException me) {
        throw new IOException(me.toString());
      }
      notify();
    } else {
      if (rcvd < length) {
        IOException ioe =
            new IOException(
                "Premature close: only "
                    + rcvd
                    + " bytes written instead of the "
                    + "expected "
                    + length);
        req.getConnection().closeDemux(ioe, false);
        req.getConnection().outputFinished();
        throw ioe;
      }

      try {
        if (length == -1) {
          if (DebugConn && trailers.length > 0) {
            System.err.println("OutS:  Sending trailers:");
            for (int idx = 0; idx < trailers.length; idx++)
              System.err.println(
                  "       " + trailers[idx].getName() + ": " + trailers[idx].getValue());
          }

          os.write(Codecs.chunkedEncode(null, 0, 0, trailers, true));
        }

        os.flush();

        if (DebugConn) System.err.println("OutS:  All data sent");
      } catch (IOException ioe) {
        req.getConnection().closeDemux(ioe, true);
        throw ioe;
      } finally {
        req.getConnection().outputFinished();
      }
    }
  }
Beispiel #4
0
  /** Invoked by the HTTPClient. */
  public int requestHandler(Request req, Response[] resp) {
    // First remove any Cookie headers we might have set for a previous
    // request

    NVPair[] hdrs = req.getHeaders();
    int length = hdrs.length;
    for (int idx = 0; idx < hdrs.length; idx++) {
      int beg = idx;
      while (idx < hdrs.length && hdrs[idx].getName().equalsIgnoreCase("Cookie")) idx++;

      if (idx - beg > 0) {
        length -= idx - beg;
        System.arraycopy(hdrs, idx, hdrs, beg, length - beg);
      }
    }
    if (length < hdrs.length) {
      hdrs = Util.resizeArray(hdrs, length);
      req.setHeaders(hdrs);
    }

    // Now set any new cookie headers

    Hashtable cookie_list = Util.getList(cookie_cntxt_list, req.getConnection().getContext());
    if (cookie_list.size() == 0) return REQ_CONTINUE; // no need to create a lot of objects

    Vector names = new Vector();
    Vector lens = new Vector();
    int version = 0;

    synchronized (cookie_list) {
      Enumeration list = cookie_list.elements();
      Vector remove_list = null;

      while (list.hasMoreElements()) {
        Cookie cookie = (Cookie) list.nextElement();

        if (cookie.hasExpired()) {
          if (LOG.isDebugEnabled()) LOG.debug("Cookie has expired and is being removed: " + cookie);

          if (remove_list == null) remove_list = new Vector();
          remove_list.addElement(cookie);
          continue;
        }

        if (cookie.sendWith(req)
            && (cookie_handler == null || cookie_handler.sendCookie(cookie, req))) {
          int len = cookie.getPath().length();
          int idx;

          // insert in correct position
          for (idx = 0; idx < lens.size(); idx++)
            if (((Integer) lens.elementAt(idx)).intValue() < len) break;

          names.insertElementAt(cookie.toExternalForm(), idx);
          lens.insertElementAt(new Integer(len), idx);

          if (cookie instanceof Cookie2)
            version = Math.max(version, ((Cookie2) cookie).getVersion());
        }
      }

      // remove any marked cookies
      // Note: we can't do this during the enumeration!
      if (remove_list != null) {
        for (int idx = 0; idx < remove_list.size(); idx++)
          cookie_list.remove(remove_list.elementAt(idx));
      }
    }

    if (!names.isEmpty()) {
      StringBuffer value = new StringBuffer();

      if (version > 0) value.append("$Version=\"" + version + "\"; ");

      value.append((String) names.elementAt(0));
      for (int idx = 1; idx < names.size(); idx++) {
        value.append("; ");
        value.append((String) names.elementAt(idx));
      }
      hdrs = Util.resizeArray(hdrs, hdrs.length + 1);
      hdrs[hdrs.length - 1] = new NVPair("Cookie", value.toString());

      // add Cookie2 header if necessary
      if (version != 1) // we currently know about version 1 only
      {
        int idx;
        for (idx = 0; idx < hdrs.length; idx++)
          if (hdrs[idx].getName().equalsIgnoreCase("Cookie2")) break;
        if (idx == hdrs.length) {
          hdrs = Util.resizeArray(hdrs, hdrs.length + 1);
          hdrs[hdrs.length - 1] = new NVPair("Cookie2", "$Version=\"1\"");
        }
      }

      req.setHeaders(hdrs);

      if (LOG.isDebugEnabled()) LOG.debug("Sending cookies '" + value + "'");
    }

    return REQ_CONTINUE;
  }