/**
   * Method to configure the HTTP response stream. This method will do whatever mechanics are
   * necessary to utilize the HTTP connection object to return an input stream to the HTTP response.
   *
   * @param http the HttpConnection object, already opened and presumably with response data waiting
   * @return an InputStream corresponding to the response data from this HttpConnection or null if
   *     not available.
   */
  protected InputStream setupResStream(HttpConnection http) throws IOException, ServerException {
    int response = http.getResponseCode();

    if (response == HttpConnection.HTTP_MOVED_PERM || response == HttpConnection.HTTP_MOVED_TEMP) {
      // Resource was moved, get a new location and retry the operation
      String newLocation = http.getHeaderField("Location");
      setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, newLocation);
      resourceMoved = true;
      return null;
    }

    InputStream input = http.openInputStream();

    if (response == HttpConnection.HTTP_OK) {

      // Catch any session cookie if one was set
      String useSession = getProperty(Stub.SESSION_MAINTAIN_PROPERTY);
      if (useSession != null && useSession.toLowerCase().equals("true")) {
        String cookie = http.getHeaderField("Set-Cookie");
        if (cookie != null) {
          addSessionCookie(getProperty(Stub.ENDPOINT_ADDRESS_PROPERTY), cookie);
        }
      }

      return input;
    } else {
      Object detail =
          decoder.decodeFault(faultHandler, input, http.getEncoding(), http.getLength());

      if (detail instanceof String) {
        if (((String) detail).indexOf("DataEncodingUnknown") != -1) {
          throw new MarshalException((String) detail);
        } else {
          throw new ServerException((String) detail);
        }
      } else {
        Object[] wrapper = (Object[]) detail;
        String message = (String) wrapper[0];
        QName name = (QName) wrapper[1];
        detail = wrapper[2];
        throw new JAXRPCException(message, new FaultDetailException(name, detail));
      }
    }
  }
    public void getResponseHeaders(final Hashtable headers) throws IOException {
      headers.clear();
      for (int i = 0; i < 10000; i++) {
        final String key = httpConnection.getHeaderFieldKey(i);
        if (key == null) {
          break;
        }
        final String value = httpConnection.getHeaderField(i);
        final String[] values = (String[]) headers.get(key);
        final String[] newValues;

        if (values == null) {
          newValues = new String[1];
          newValues[0] = value;
        } else {
          newValues = new String[values.length + 1];
          System.arraycopy(values, 0, newValues, 0, values.length);
          newValues[values.length] = value;
        }
        headers.put(key, newValues);
      }
    }
  /** {@inheritDoc} */
  public InputStream resourceRequested(DocumentInfo docInfo) {
    InputStream is = null;
    String url = docInfo.getUrl();

    String linkDomain = getDomainForLinks(url);

    // Visited links
    if (docInfo.getExpectedContentType()
        == DocumentInfo.TYPE_HTML) { // Only mark base documents as visited links

      if (linkDomain != null) {
        Vector hostVisitedLinks = (Vector) visitedLinks.get(linkDomain);
        if (hostVisitedLinks == null) {
          hostVisitedLinks = new Vector();
          visitedLinks.put(linkDomain, hostVisitedLinks);
        }
        if (!hostVisitedLinks.contains(url)) {
          hostVisitedLinks.addElement(url);
          Storage.addHistory(linkDomain, url);
        }
      } else {
        System.out.println("Link domain null for " + url);
      }
    }

    String params = docInfo.getParams();
    if ((!docInfo.isPostRequest()) && (params != null) && (!params.equals(""))) {
      url = url + "?" + params;
    }

    // See if page/image is in the cache
    // caching will be used only if there are no parameters and no cookies (Since if they are this
    // is probably dynamic content)
    boolean useCache = false;
    if (((docInfo.getExpectedContentType() == DocumentInfo.TYPE_HTML)
            && (CACHE_HTML)
            && ((params == null) || (params.equals("")))
            && (!cookiesExistForDomain(linkDomain)))
        || ((docInfo.getExpectedContentType() == DocumentInfo.TYPE_IMAGE) && (CACHE_IMAGES))) {
      useCache = true;
      InputStream imageIS = Storage.getResourcefromCache(url);
      if (imageIS != null) {
        return imageIS;
      }
    }

    // Handle the file protocol
    if (url.startsWith("file://")) {
      return getFileStream(docInfo);
    }

    try {
      HttpConnection hc = (HttpConnection) Connector.open(url);
      String encoding = null;
      if (docInfo.isPostRequest()) {
        encoding = "application/x-www-form-urlencoded";
      }
      if (!docInfo.getEncoding().equals(DocumentInfo.ENCODING_ISO)) {
        encoding = docInfo.getEncoding();
      }
      // hc.setRequestProperty("Accept_Language","en-US");

      // String domain=hc.getHost(); // sub.domain.com / sub.domain.co.il
      String domain =
          linkDomain; // will return one of the following formats: sub.domain.com / sub.domain.co.il

      sendCookies(domain, hc);
      domain = domain.substring(domain.indexOf('.')); // .domain.com / .domain.co.il
      if (domain.indexOf('.', 1)
          != -1) { // Make sure that we didn't get just .com - TODO - however note that if the
        // domain was domain.co.il - it can be here .co.il
        sendCookies(domain, hc);
      }

      if (encoding != null) {
        hc.setRequestProperty("Content-Type", encoding);
      }

      if (docInfo.isPostRequest()) {
        hc.setRequestMethod(HttpConnection.POST);
        byte[] paramBuf = params.getBytes();
        hc.setRequestProperty("Content-Length", "" + paramBuf.length);
        OutputStream os = hc.openOutputStream();
        os.write(paramBuf);
        os.close();

        // os.flush(); // flush is said to be problematic in some devices, uncomment if it is
        // necessary for your device
      }

      if (docInfo.getExpectedContentType()
          == DocumentInfo
              .TYPE_HTML) { // We perform these checks only for text (i.e. main page), for images we
        // just send what the server sends and "hope for the best"
        String contentTypeStr = hc.getHeaderField("content-type").toLowerCase();
        if (contentTypeStr != null) {
          if ((contentTypeStr.startsWith("text/"))
              || (contentTypeStr.startsWith("application/xhtml"))
              || (contentTypeStr.startsWith("application/vnd.wap"))) {
            docInfo.setExpectedContentType(DocumentInfo.TYPE_HTML);
          } else if (contentTypeStr.startsWith("image/")) {
            docInfo.setExpectedContentType(DocumentInfo.TYPE_IMAGE);
            hc.close();
            return getStream("<img src=\"" + url + "\">", null);
          } else {
            hc.close();
            return getStream("Content type " + contentTypeStr + " is not supported.", "Error");
          }
        }

        int charsetIndex = contentTypeStr.indexOf("charset=");
        String charset = contentTypeStr.substring(charsetIndex + 8);
        if ((charset.startsWith("utf-8"))
            || (charset.startsWith("utf8"))) { // startwith to allow trailing white spaces
          docInfo.setEncoding(DocumentInfo.ENCODING_UTF8);
        }
      }

      int i = 0;
      while (hc.getHeaderFieldKey(i) != null) {
        if (hc.getHeaderFieldKey(i).equals("set-cookie")) {
          // addCookie(hc.getHeaderField(i), hc);
          addCookie(hc.getHeaderField(i), url);
        }

        i++;
      }

      int response = hc.getResponseCode();
      if (response / 100 == 3) { // 30x code is redirect
        String newURL = hc.getHeaderField("Location");
        if (newURL != null) {
          hc.close();
          docInfo.setUrl(newURL);
          // docInfo.setPostRequest(false);
          // docInfo.setParams(null); //reset params
          return resourceRequested(docInfo);
        }
      }
      is = hc.openInputStream();

      if (useCache) {
        byte[] buf = getBuffer(is);
        Storage.addResourceToCache(url, buf, false);
        ByteArrayInputStream bais = new ByteArrayInputStream(buf);
        is.close();
        hc.close(); // all the data is in the buffer
        return bais;
      }

    } catch (IOException e) {
      System.out.println("HttpRequestHandler->IOException: " + e.getMessage());
    } catch (IllegalArgumentException e) { // For malformed URL
      System.out.println("HttpRequestHandler->IllegalArgumentException: " + e.getMessage());
    }

    return is;
  }
  private synchronized void httpPostRequest(String postData) throws IOException {
    try {
      HttpConnection hc = (HttpConnection) Connector.open(pollingUrl);
      hc.setRequestMethod(HttpConnection.POST);
      hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
      hc.setRequestProperty("Host", "host");

      StringBuffer out = new StringBuffer();
      if (sessionId == null) {
        out.append("0");
        keys = new Vector();
      } else out.append(sessionId);

      do {
        if (keys.size() == 0) {
          initKeys();
        }
        out.append(";").append((String) keys.lastElement());
        keys.removeElementAt(keys.size() - 1);
      } while (keys.size() == 0);

      out.append(",").append(postData);

      int outLen = out.length();
      // hc.setRequestProperty("Content-Length", String.valueOf(outLen));

      byte bytes[] = new byte[outLen];
      for (int i = 0; i < outLen; i++) {
        bytes[i] = (byte) out.charAt(i);
      }

      OutputStream os = hc.openOutputStream();
      os.write(bytes);
      os.close();

      int resp = hc.getResponseCode();

      if (resp != HttpConnection.HTTP_OK) throw new IOException("HTTP Error code" + resp);

      InputStream is = hc.openInputStream();

      String cookie = hc.getHeaderField("Set-Cookie");
      int expires = cookie.indexOf(';');
      if (expires > 0) cookie = cookie.substring(3, expires);

      if (cookie.endsWith(":0")) {
        opened = false;
        error = cookie;
      }

      if (sessionId == null) {
        sessionId = cookie;
      }

      byte data[];
      int inLen = (int) hc.getLength();

      if (inLen < 0) {
        throw new Exception("Content-Length missing"); // TODO:
      } else {
        int actual = 0;
        int bytesread = 0;
        data = new byte[inLen];
        while ((bytesread != inLen) && (actual != -1)) {
          actual = is.read(data, bytesread, inLen - bytesread);
          bytesread += actual;
        }

        if (inLen > 0) inStack.addElement(data);
      }
      is.close();
      hc.close();
    } catch (Exception e) {
      opened = false;
      error = e.toString();
      // #ifdef DEBUG
      // #             e.printStackTrace();
      // #endif
    }
  }
  public InputStream makeRequest(String url, OutputStream pos) throws IOException {
    HttpConnection conn = null;
    ByteArrayOutputStream bos = null;
    DataInputStream is = null;
    DataOutputStream os = null;
    InputStream pis = null;

    try {
      conn = (HttpConnection) Connector.open(url, Connector.READ_WRITE);
      conn.setRequestMethod(HttpConnection.POST);
      conn.setRequestProperty("Content-Type", "application/octet-stream");
      conn.setRequestProperty("Accept", "application/octet-stream");

      if (sessionCookie == null) {
        conn.setRequestProperty("version", "???");
      } else {
        conn.setRequestProperty("cookie", sessionCookie);
      }

      // Getting the output stream may flush the headers
      os = conn.openDataOutputStream();
      os.write(pos.getBytes());
      os.close();

      int responseCode;
      try {
        responseCode = conn.getResponseCode();
      } catch (IOException e) {
        throw new IOException("No response from " + url);
      }

      if (responseCode != HttpConnection.HTTP_OK) {
        throw new IllegalArgumentException();
      }

      bos = new ByteArrayOutputStream();
      {
        is = conn.openDataInputStream();
        String sc = conn.getHeaderField("set-cookie");
        if (sc != null) {
          sessionCookie = sc;
        }

        while (true) {
          int ch = is.read();
          if (ch == -1) break;

          bos.write(ch);
        }

        is.close();
        is = null;

        conn.close();
        conn = null;
      }
      pis = new InputStream(bos.toByteArray());

      bos.close();
      bos = null;
    } catch (Exception e) {
      e.printStackTrace();
      try {
        if (conn != null) {
          conn.close();
          conn = null;
        }

        if (bos != null) {
          bos.close();
          bos = null;
        }

        if (is != null) {
          is.close();
          is = null;
        }
      } catch (Exception exc) {
      }
      throw new IOException();
    }

    return pis;
  }
Exemple #6
0
  /**
   * Makes a http request to URL using the set method (HttpConnection.GET or HttpConnection.POST)
   * and the supplied request parameters.
   *
   * @param url
   * @param requestMethod
   * @param requestProperties User supplied Http request header parameters.
   * @param data if method is POST then the post data are in this array.
   * @param updateCurrentPage if set to true the HttpClient will remember the URL of this request in
   *     order to handle feature relative path requests
   * @return
   * @throws InterruptedIOException
   * @throws SecurityException
   * @throws IOException
   * @throws IllegalStateException
   * @throws Exception
   */
  public Response requestResource(
      String url,
      String requestMethod,
      Hashtable requestProperties,
      byte[] data,
      boolean updateCurrentPage)
      throws InterruptedIOException, SecurityException, IOException, IllegalStateException,
          Exception {
    url = getAbsolutEncodedURL(url);

    int idx = url.indexOf("://");
    if (idx == -1) throw new IllegalArgumentException("URL must start with the protocol.");

    String protocol = url.substring(0, idx);

    if (protocol.equals("file")) {
      // Log.logInfo("File: ["+url+"]");
      InputStream in = null;
      try {
        in = connector.openInputStream(url);
      } catch (Exception e) {
        Log.logDebug("Exception:" + e.getClass() + ": " + e.getMessage());
      }

      if (in == null) {
        Log.logWarn("Failed to load local resource " + url);
        return null;
      }

      Response result = new Response("", "file", url.substring(7), in);
      if (updateCurrentPage) currentResponse = result;

      return result;
    }

    if (protocol.equals("rms")) {
      // Log.logInfo("File: ["+url+"]");
      InputStream in = null;
      String rms = url.substring(6);
      try {
        in = connector.rmsRead(rms);
      } catch (Exception e) {
        Log.logDebug("Exception:" + e.getClass() + ": " + e.getMessage());
      }

      if (in == null) {
        Log.logWarn("Failed to load local resource " + url);
        return null;
      }

      Response result = new Response("", "rms", rms, in);
      if (updateCurrentPage) currentResponse = result;

      return result;
    }

    HttpConnection conn = null;
    Log.logInfo(requestMethod + " [" + url + "]");

    try { // the resource is located remotelly. Try to retrieve it.
      int mode = Connector.READ_WRITE;
      // XXX CREATING A READ ONLY CONNECTION WILL CAUSE SOME BLACKBERRY DEVICES NOT TO WORK. XXX
      // if(HttpConnection.POST.equals(requestMethod) && data!=null) mode=Connector.READ_WRITE;
      int code;
      Response result = new Response();
      registerConnection(result);

      conn = (HttpConnection) connector.open(url, mode, true);
      conn.setRequestMethod(requestMethod);
      for (int i = 0; i < defaultHeaderValues.length; ++i) {
        conn.setRequestProperty(defaultHeaderValues[i][0], defaultHeaderValues[i][1]);
      }

      if (requestProperties != null) {
        Enumeration propKeys = requestProperties.keys();
        while (propKeys.hasMoreElements()) {
          String key = (String) propKeys.nextElement();
          String val = (String) requestProperties.get(key);
          conn.setRequestProperty(key, val);
        }
      }

      // add cookies
      String cookies = getCookies(conn, conn.getFile());
      if (cookies.length() > 0) {
        conn.setRequestProperty("Cookie", cookies);
      }

      // add referer
      if (currentResponse != null && currentResponse.getProtocol().equals("file") == false) {
        String q = currentResponse.getQuery();
        if (q != null) q = "?" + q;
        else q = "";
        String referer = currentResponse.getBaseURL() + currentResponse.getFile() + q;
        conn.setRequestProperty("Referer", referer);
      }
      if (mode == Connector.READ_WRITE && data != null) // exoume na grapsoume kiolas.
      {
        conn.setRequestProperty("Content-Length", "" + data.length);
        OutputStream out = conn.openOutputStream();
        out.write(data);
        out.close();
        Log.logDebug("Post data[" + data.length + "] sent.");
      }

      Log.logDebug("Attempting to retrieve response code..");
      code = conn.getResponseCode();
      result.setConnection(conn);
      Log.logInfo("Response " + code + " " + conn.getResponseMessage());

      for (int i = 0; i < 100; ++i) {
        String key = conn.getHeaderFieldKey(i);
        if (key == null) break;

        if (key.toLowerCase().equals("set-cookie")) {
          // the cookieStr may be more than one cookies separated by commas.
          // First we split the cookies and then we parse them.
          // this is a bit tricky since a cookie may contain commas as well...(who thought of that
          // delimiter anyway?)
          Vector cookieStrings = Cookie.splitCookies(conn.getHeaderField(i));
          for (int j = 0; j < cookieStrings.size(); ++j)
            saveCookie((String) cookieStrings.elementAt(j), conn.getHost());
        } else Log.logDebug(key + ": " + conn.getHeaderField(i));
      }

      if (code == HttpConnection.HTTP_MOVED_PERM
          || code == HttpConnection.HTTP_MOVED_TEMP
          || // 301 or 307 redirect using the same method (post of get)
          code
              == HttpConnection.HTTP_SEE_OTHER) // must redirect using the GET method (see protocol)
      {
        if (updateCurrentPage) currentResponse = result;

        if (result.isCanceled()) throw new InterruptedIOException("Redirect canceled by user.");

        redirectCount++;
        String redirect = conn.getHeaderField("location");
        Log.logInfo("Redirect[" + redirectCount + "] " + code + " to location: " + redirect);
        if (redirectCount < MAX_REDIRECTS) {
          try {
            conn.close();
          } catch (IOException e) {
            Log.logWarn("HttpClient: Failed to close connection on redirect.", e);
          }

          conn = null; // make old connection null so on finally we will not try to unregister it
          // again.
          if (code == HttpConnection.HTTP_MOVED_PERM || code == HttpConnection.HTTP_MOVED_TEMP)
            return requestResource(
                redirect, requestMethod, requestProperties, data, updateCurrentPage);
          else
            return requestResource(
                redirect, HttpConnection.GET, requestProperties, data, updateCurrentPage);
        } else {
          throw new IllegalStateException("Too many redirects.");
        }
      } else // response is 200 or another http code.
      {
        if (updateCurrentPage
            && code == HttpConnection.HTTP_OK) // updateCurrentPage only when response is 200 (OK)
        currentResponse = result;

        return result;
      }
    } catch (Exception ex) {
      if (ex instanceof InterruptedIOException) Log.logInfo("USER Closed connection to " + url);
      else Log.logError("Request to " + url + " failed.", ex);

      if (conn != null) {
        try {
          conn.close();
        } catch (IOException e) {
          Log.logWarn("Failed to close the connection.", e);
        }
      }
      throw ex;
    } finally {
      redirectCount = 0;
    }
  }