All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ee.jakarta.tck.ws.rs.common.webclient.http.HttpRequest Maven / Gradle / Ivy

/*
 * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * $Id$
 */

package ee.jakarta.tck.ws.rs.common.webclient.http;

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnection;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;

import ee.jakarta.tck.ws.rs.lib.util.TestUtil;
import ee.jakarta.tck.ws.rs.common.webclient.Util;

/**
 * Represents an HTTP client Request
 */

public class HttpRequest {

  static {
    // if (TestUtil.traceflag) {
    //   System.setProperty("org.apache.commons.logging.Log",
    //       "ee.jakarta.tck.ws.rs.common.webclient.log.WebLog");
    //   System.setProperty(
    //       "org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
    // }
  }

  /**
   * Default HTTP port.
   */
  public static int DEFAULT_HTTP_PORT = 80;

  /**
   * Default HTTP SSL port.
   */
  public static final int DEFAULT_SSL_PORT = 443;

  /**
   * No authentication
   */
  public static final int NO_AUTHENTICATION = 0;

  /**
   * Basic authentication
   */
  public static final int BASIC_AUTHENTICATION = 1;

  /**
   * Digest authenctication
   */
  public static final int DIGEST_AUTHENTICATION = 2;

  /**
   * Method representation of request.
   */
  private HttpMethod _method = null;

  /**
   * Target web container host
   */
  private String _host = null;

  /**
   * Target web container port
   */
  private int _port = DEFAULT_HTTP_PORT;

  /**
   * Is the request going over SSL
   */
  private boolean _isSecure = false;

  /**
   * HTTP state
   */
  private HttpState _state = null;

  /**
   * Original request line for this request.
   */
  private String _requestLine = null;

  /**
   * Authentication type for current request
   */
  private int _authType = NO_AUTHENTICATION;

  /**
   * Flag to determine if session tracking will be used or not.
   */
  private boolean _useCookies = false;

  /**
   * Content length of request body.
   */
  private int _contentLength = 0;

  /**
   * FollowRedirects
   */
  private boolean _redirect = false;

  Header[] _headers = null;

  protected HttpClient client = null;

  /**
   * Creates new HttpRequest based of the passed request line. The request line
   * provied must be in the form of:
* *
   *     METHOD PATH HTTP-VERSION
   *     Ex.  GET /index.html HTTP/1.0
   * 
*/ public HttpRequest(String requestLine, String host, int port) { client = new HttpClient(); _method = MethodFactory.getInstance(requestLine); _method.setFollowRedirects(false); _host = host; _port = port; if (port == DEFAULT_SSL_PORT) { _isSecure = true; } // If we got this far, the request line is in the proper // format _requestLine = requestLine; } /* * public methods * ======================================================================== */ /** * getRequestPath returns the request path for this particular * request. * * @return String request path */ public String getRequestPath() { return _method.getPath(); } /** * getRequestMethod returns the request type, i.e., GET, POST, * etc. * * @return String request type */ public String getRequestMethod() { return _method.getName(); } /** * isSecureConnection() indicates if the Request is secure or * not. * * @return boolean whether Request is using SSL or not. */ public boolean isSecureRequest() { return _isSecure; } /** * setSecureRequest configures this request to use SSL. * * @param secure * - whether the Request uses SSL or not. */ public void setSecureRequest(boolean secure) { _isSecure = secure; } /** * setContent will set the body for this request. Note, this is * only valid for POST and PUT operations, however, if called and the request * represents some other HTTP method, it will be no-op'd. * * @param content * request content */ public void setContent(String content) { if (_method instanceof EntityEnclosingMethod) { ((EntityEnclosingMethod) _method) .setRequestEntity(new StringRequestEntity(content)); } _contentLength = content.length(); } /** * setAuthenticationCredentials configures the request to * perform authentication. * *

username and password cannot be null. *

* *

* It is legal for realm to be null. *

* * @param username * the user * @param password * the user's password * @param authType * authentication type * @param realm * authentication realm */ public void setAuthenticationCredentials(String username, String password, int authType, String realm) { if (username == null) { throw new IllegalArgumentException("Username cannot be null"); } if (password == null) { throw new IllegalArgumentException("Password cannot be null"); } UsernamePasswordCredentials cred = new UsernamePasswordCredentials(username, password); AuthScope scope = new AuthScope(_host, _port, realm); getState().setCredentials(scope, cred); TestUtil.logTrace("[HttpRequest] Added credentials for '" + username + "' with password '" + password + "' in realm '" + realm + "'"); _authType = authType; } /** * addRequestHeader adds a request header to this request. If a * request header of the same name already exists, the new value, will be * added to the set of already existing values. * * NOTE: that header names are not case-sensitive. * * @param headerName * request header name * @param headerValue * request header value */ public void addRequestHeader(String headerName, String headerValue) { _method.addRequestHeader(headerName, headerValue); TestUtil.logTrace("[HttpRequest] Added request header: " + _method.getRequestHeader(headerName).toExternalForm()); } public void addRequestHeader(String header) { StringTokenizer st = new StringTokenizer(header, "|"); while (st.hasMoreTokens()) { String h = st.nextToken(); if (h.toLowerCase().startsWith("cookie")) { createCookie(h); continue; } int col = h.indexOf(':'); addRequestHeader(h.substring(0, col).trim(), h.substring(col + 1).trim()); } } /** * setRequestHeader sets a request header for this request * overwritting any previously existing header/values with the same name. * * NOTE: Header names are not case-sensitive. * * @param headerName * request header name * @param headerValue * request header value */ public void setRequestHeader(String headerName, String headerValue) { _method.setRequestHeader(headerName, headerValue); TestUtil.logTrace("[HttpRequest] Set request header: " + _method.getRequestHeader(headerName).toExternalForm()); } /** * setFollowRedirects indicates whether HTTP redirects are * followed. By default, redirects are not followed. */ public void setFollowRedirects(boolean followRedirects) { _method.setFollowRedirects(followRedirects); } /** * getFollowRedirects indicates whether HTTP redirects are * followed. */ public boolean getFollowRedirects() { return _method.getFollowRedirects(); } /** * setState will set the HTTP state for the current request (i.e. * session tracking). This has the side affect */ public void setState(HttpState state) { _state = state; _useCookies = true; } /** * execute will dispatch the current request to the target * server. * * @return HttpResponse the server's response. * @throws IOException * if an I/O error occurs during dispatch. */ public HttpResponse execute() throws IOException, HttpException { String method; int defaultPort; ProtocolSocketFactory factory; if (_method.getFollowRedirects()) { client = new HttpClient(); if (_isSecure) { method = "https"; defaultPort = DEFAULT_SSL_PORT; factory = new SSLProtocolSocketFactory(); } else { method = "http"; defaultPort = DEFAULT_HTTP_PORT; factory = new DefaultProtocolSocketFactory(); } Protocol protocol = new Protocol(method, factory, defaultPort); HttpConnection conn = new HttpConnection(_host, _port, protocol); if (conn.isOpen()) { throw new IllegalStateException("Connection incorrectly opened"); } conn.open(); TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine + "' to target server at '" + _host + ":" + _port + "'"); addSupportHeaders(); _headers = _method.getRequestHeaders(); TestUtil.logTrace( "########## The real value set: " + _method.getFollowRedirects()); client.getHostConfiguration().setHost(_host, _port, protocol); client.executeMethod(_method); return new HttpResponse(_host, _port, _isSecure, _method, getState()); } else { if (_isSecure) { method = "https"; defaultPort = DEFAULT_SSL_PORT; factory = new SSLProtocolSocketFactory(); } else { method = "http"; defaultPort = DEFAULT_HTTP_PORT; factory = new DefaultProtocolSocketFactory(); } Protocol protocol = new Protocol(method, factory, defaultPort); HttpConnection conn = new HttpConnection(_host, _port, protocol); if (conn.isOpen()) { throw new IllegalStateException("Connection incorrectly opened"); } conn.open(); TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine + "' to target server at '" + _host + ":" + _port + "'"); addSupportHeaders(); _headers = _method.getRequestHeaders(); TestUtil.logTrace( "########## The real value set: " + _method.getFollowRedirects()); _method.execute(getState(), conn); return new HttpResponse(_host, _port, _isSecure, _method, getState()); } } /** * Returns the current state for this request. * * @return HttpState current state */ public HttpState getState() { if (_state == null) { _state = new HttpState(); } return _state; } public String toString() { StringBuffer sb = new StringBuffer(255); sb.append("[REQUEST LINE] -> ").append(_requestLine).append('\n'); if (_headers != null && _headers.length != 0) { for (Header _header : _headers) { sb.append(" [REQUEST HEADER] -> "); sb.append(_header.toExternalForm()).append('\n'); } } if (_contentLength != 0) { sb.append(" [REQUEST BODY LENGTH] -> ").append(_contentLength); sb.append('\n'); } return sb.toString(); } /* * private methods * ======================================================================== */ private void createCookie(String cookieHeader) { String cookieLine = cookieHeader.substring(cookieHeader.indexOf(':') + 1) .trim(); StringTokenizer st = new StringTokenizer(cookieLine, " ;"); Cookie cookie = new Cookie(); cookie.setVersion(1); getState(); if (cookieLine.indexOf("$Version") == -1) { cookie.setVersion(0); _method.getParams().setCookiePolicy(CookiePolicy.NETSCAPE); } while (st.hasMoreTokens()) { String token = st.nextToken(); if (token.charAt(0) != '$' && !token.startsWith("Domain") && !token.startsWith("Path")) { cookie.setName(token.substring(0, token.indexOf('='))); cookie.setValue(token.substring(token.indexOf('=') + 1)); } else if (token.indexOf("Domain") > -1) { cookie.setDomainAttributeSpecified(true); cookie.setDomain(token.substring(token.indexOf('=') + 1)); } else if (token.indexOf("Path") > -1) { cookie.setPathAttributeSpecified(true); cookie.setPath(token.substring(token.indexOf('=') + 1)); } } _state.addCookie(cookie); } /** * Adds any support request headers necessary for this request. These headers * will be added based on the state of the request. */ private void addSupportHeaders() { // Authentication headers // NOTE: Possibly move logic to generic method switch (_authType) { case NO_AUTHENTICATION: break; case BASIC_AUTHENTICATION: setBasicAuthorizationHeader(); break; case DIGEST_AUTHENTICATION: throw new UnsupportedOperationException( "Digest Authentication is not currently " + "supported"); } // A Host header will be added to each request to handle // cases where virtual hosts are used, or there is no DNS // available on the system where the container is running. setHostHeader(); // Content length header setContentLengthHeader(); // Cookies setCookieHeader(); } /** * Sets a basic authentication header in the request is Request is configured * to use basic authentication */ private void setBasicAuthorizationHeader() { UsernamePasswordCredentials cred = (UsernamePasswordCredentials) getState() .getCredentials(new AuthScope(_host, _port, null)); String authString = null; if (cred != null) { authString = "Basic " + Util.getBase64EncodedString( cred.getUserName() + ":" + cred.getPassword()); } else { TestUtil.logTrace("[HttpRequest] NULL CREDENTIALS"); } _method.setRequestHeader("Authorization", authString); } /** * Sets a Content-Length header in the request if content is present */ private void setContentLengthHeader() { if (_contentLength > 0) { _method.setRequestHeader("Content-Length", Integer.toString(_contentLength)); } } /** * Sets a host header in the request. If the configured host value is an IP * address, the Host header will be sent, but without any value. * * If we adhered to the HTTP/1.1 spec, the Host header must be empty of the * target server is identified via IP address. However, no user agents I've * tested follow this. And if a custom client library does this, it may not * work properly with the target server. For now, the Host request-header will * always have a value. */ private void setHostHeader() { if (_port == DEFAULT_HTTP_PORT || _port == DEFAULT_SSL_PORT) { _method.setRequestHeader("Host", _host); } else { _method.setRequestHeader("Host", _host + ":" + _port); } } /** * Sets a Cookie header if this request is using cookies. */ private void setCookieHeader() { if (_useCookies) { Cookie[] cookies = _state.getCookies(); if (cookies != null && cookies.length > 0) { Header cHeader = CookiePolicy.getCookieSpec(CookiePolicy.RFC_2109) .formatCookieHeader(_state.getCookies()); if (cHeader != null) { _method.setRequestHeader(cHeader); } } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy