<commit_before>/*
 * Copyright 2003-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * You are receiving this code free of charge, which represents many hours of
 * effort from other individuals and corporations.  As a responsible member 
 * of the community, you are asked (but not required) to donate any 
 * enhancements or improvements back to the community under a similar open 
 * source license.  Thank you. -TMN
 */
package groovyx.net.http;

import static groovyx.net.http.URIBuilder.convertToURI;
import groovy.lang.Closure;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.cookie.params.CookieSpecPNames;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.runtime.MethodClosure;

/** <p>
 * Groovy DSL for easily making HTTP requests, and handling request and response
 * data.  This class adds a number of convenience mechanisms built on top of 
 * Apache HTTPClient for things like URL-encoded POSTs and REST requests that 
 * require building and parsing JSON or XML.  Convenient access to a few common
 * authentication methods is also available.</p>
 * 
 * 
 * <h3>Conventions</h3>
 * <p>HTTPBuilder has properties for default headers, URI, contentType, etc.  
 * All of these values are also assignable (and in many cases, in much finer 
 * detail) from the {@link RequestConfigDelegate} as well.  In any cases where the value
 * is not set on the delegate (from within a request closure,) the builder's 
 * default value is used.  </p>
 * 
 * <p>For instance, any methods that do not take a <code>uri</code> parameter 
 * assume you will set the <code>uri</code> property in the request closure or 
 * use HTTPBuilder's assigned {@link #getUri() default URI}.</p>
 * 
 * 
 * <h3>Response Parsing</h3>
 * <p>By default, HTTPBuilder uses {@link ContentType#ANY} as the default 
 * content-type.  This means the value of the request's <code>Accept</code> 
 * header is <code>&#42;/*</code>, and the response parser is determined 
 * based on the response <code>content-type</code> header. </p>
 * 
 * <p><strong>If</strong> any contentType is given (either in 
 * {@link #setContentType(Object)} or as a request method parameter), the 
 * builder will attempt to parse the response using that content-type, 
 * regardless of what the server actually responds with.  </p>
 * 
 *  
 * <h3>Examples:</h3>
 * Perform an HTTP GET and print the response:
 * <pre>
 *   def http = new HTTPBuilder('http://www.google.com')
 *   
 *   http.get( path : '/search', 
 *             contentType : TEXT,
 *             query : [q:'Groovy'] ) { resp, reader ->
 *     println "response status: ${resp.statusLine}"
 *     println 'Response data: -----'
 *     System.out << reader
 *     println '\n--------------------'
 *   }
 * </pre>
 *   
 * Long form for other HTTP methods, and response-code-specific handlers.  
 * This is roughly equivalent to the above example.
 *   
 * <pre>
 *   def http = new HTTPBuilder('http://www.google.com/search?q=groovy')
 *   
 *   http.request( GET, TEXT ) { req ->
 *   
 *     // executed for all successful responses:
 *     response.success = { resp, reader ->
 *       println 'my response handler!'
 *       assert resp.statusLine.statusCode == 200
 *       println resp.statusLine
 *       System.out << reader // print response stream
 *     }
 *     
 *     // executed only if the response status code is 401:
 *     response.'404' = { resp -> 
 *       println 'not found!'
 *     }
 *   }
 * </pre>
 *   
 * You can also set a default response handler called for any status
 * code > 399 that is not matched to a specific handler. Setting the value
 * outside a request closure means it will apply to all future requests with
 * this HTTPBuilder instance:
 * <pre>
 *   http.handler.failure = { resp ->
 *     println "Unexpected failure: ${resp.statusLine}"
 *   }
 * </pre>
 *   
 *   
 * And...  Automatic response parsing for registered content types!
 *   
 * <pre>
 *   http.request( 'http://ajax.googleapis.com', GET, JSON ) {
 *     uri.path = '/ajax/services/search/web'
 *     uri.query = [ v:'1.0', q: '<NAME>' ]
 *     
 *     response.success = { resp, json ->
 *       assert json.size() == 3
 *       println "Query response: "
 *       json.responseData.results.each {
 *         println "  ${it.titleNoFormatting} : ${it.visibleUrl}"
 *       }
 *     }
 *   }
 * </pre>
 * 
 * 
 * @author <a href='mailto:<EMAIL>'><NAME></a>
 */
public class HTTPBuilder {
	
	protected AbstractHttpClient client;
	protected URIBuilder defaultURI = null;
	protected AuthConfig auth = new AuthConfig( this );
	
	protected final Log log = LogFactory.getLog( getClass() );
	
	protected Object defaultContentType = ContentType.ANY;
	protected Object defaultRequestContentType = null;
	protected final Map<Object,Closure> defaultResponseHandlers = 
		new StringHashMap<Closure>( buildDefaultResponseHandlers() );
	protected ContentEncodingRegistry contentEncodingHandler = new ContentEncodingRegistry();
	
	protected final Map<Object,Object> defaultRequestHeaders = new StringHashMap<Object>();
	
	protected EncoderRegistry encoders = new EncoderRegistry();
	protected ParserRegistry parsers = new ParserRegistry();
	
	public HTTPBuilder() { 
		super();
		HttpParams defaultParams = new BasicHttpParams();
		defaultParams.setParameter( CookieSpecPNames.DATE_PATTERNS,
		        Arrays.asList("EEE, dd-MMM-yyyy HH:mm:ss z", 
		        		"EEE, dd MMM yyyy HH:mm:ss z") );
		this.client = new DefaultHttpClient(defaultParams);
		this.setContentEncoding( ContentEncoding.Type.GZIP, 
				ContentEncoding.Type.DEFLATE );
	}<commit_msg>GMOD-158 httpclient instance is relegated to a createClient function<commit_after>/*
 * Copyright 2003-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * You are receiving this code free of charge, which represents many hours of
 * effort from other individuals and corporations.  As a responsible member 
 * of the community, you are asked (but not required) to donate any 
 * enhancements or improvements back to the community under a similar open 
 * source license.  Thank you. -TMN
 */
package groovyx.net.http;

import static groovyx.net.http.URIBuilder.convertToURI;
import groovy.lang.Closure;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.cookie.params.CookieSpecPNames;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.runtime.MethodClosure;

/** <p>
 * Groovy DSL for easily making HTTP requests, and handling request and response
 * data.  This class adds a number of convenience mechanisms built on top of 
 * Apache HTTPClient for things like URL-encoded POSTs and REST requests that 
 * require building and parsing JSON or XML.  Convenient access to a few common
 * authentication methods is also available.</p>
 * 
 * 
 * <h3>Conventions</h3>
 * <p>HTTPBuilder has properties for default headers, URI, contentType, etc.  
 * All of these values are also assignable (and in many cases, in much finer 
 * detail) from the {@link RequestConfigDelegate} as well.  In any cases where the value
 * is not set on the delegate (from within a request closure,) the builder's 
 * default value is used.  </p>
 * 
 * <p>For instance, any methods that do not take a <code>uri</code> parameter 
 * assume you will set the <code>uri</code> property in the request closure or 
 * use HTTPBuilder's assigned {@link #getUri() default URI}.</p>
 * 
 * 
 * <h3>Response Parsing</h3>
 * <p>By default, HTTPBuilder uses {@link ContentType#ANY} as the default 
 * content-type.  This means the value of the request's <code>Accept</code> 
 * header is <code>&#42;/*</code>, and the response parser is determined 
 * based on the response <code>content-type</code> header. </p>
 * 
 * <p><strong>If</strong> any contentType is given (either in 
 * {@link #setContentType(Object)} or as a request method parameter), the 
 * builder will attempt to parse the response using that content-type, 
 * regardless of what the server actually responds with.  </p>
 * 
 *  
 * <h3>Examples:</h3>
 * Perform an HTTP GET and print the response:
 * <pre>
 *   def http = new HTTPBuilder('http://www.google.com')
 *   
 *   http.get( path : '/search', 
 *             contentType : TEXT,
 *             query : [q:'Groovy'] ) { resp, reader ->
 *     println "response status: ${resp.statusLine}"
 *     println 'Response data: -----'
 *     System.out << reader
 *     println '\n--------------------'
 *   }
 * </pre>
 *   
 * Long form for other HTTP methods, and response-code-specific handlers.  
 * This is roughly equivalent to the above example.
 *   
 * <pre>
 *   def http = new HTTPBuilder('http://www.google.com/search?q=groovy')
 *   
 *   http.request( GET, TEXT ) { req ->
 *   
 *     // executed for all successful responses:
 *     response.success = { resp, reader ->
 *       println 'my response handler!'
 *       assert resp.statusLine.statusCode == 200
 *       println resp.statusLine
 *       System.out << reader // print response stream
 *     }
 *     
 *     // executed only if the response status code is 401:
 *     response.'404' = { resp -> 
 *       println 'not found!'
 *     }
 *   }
 * </pre>
 *   
 * You can also set a default response handler called for any status
 * code > 399 that is not matched to a specific handler. Setting the value
 * outside a request closure means it will apply to all future requests with
 * this HTTPBuilder instance:
 * <pre>
 *   http.handler.failure = { resp ->
 *     println "Unexpected failure: ${resp.statusLine}"
 *   }
 * </pre>
 *   
 *   
 * And...  Automatic response parsing for registered content types!
 *   
 * <pre>
 *   http.request( 'http://ajax.googleapis.com', GET, JSON ) {
 *     uri.path = '/ajax/services/search/web'
 *     uri.query = [ v:'1.0', q: '<NAME>' ]
 *     
 *     response.success = { resp, json ->
 *       assert json.size() == 3
 *       println "Query response: "
 *       json.responseData.results.each {
 *         println "  ${it.titleNoFormatting} : ${it.visibleUrl}"
 *       }
 *     }
 *   }
 * </pre>
 * 
 * 
 * @author <a href='mailto:<EMAIL>'><NAME></a>
 */
public class HTTPBuilder {
	
	protected AbstractHttpClient client;
	protected URIBuilder defaultURI = null;
	protected AuthConfig auth = new AuthConfig( this );
	
	protected final Log log = LogFactory.getLog( getClass() );
	
	protected Object defaultContentType = ContentType.ANY;
	protected Object defaultRequestContentType = null;
	protected final Map<Object,Closure> defaultResponseHandlers = 
		new StringHashMap<Closure>( buildDefaultResponseHandlers() );
	protected ContentEncodingRegistry contentEncodingHandler = new ContentEncodingRegistry();
	
	protected final Map<Object,Object> defaultRequestHeaders = new StringHashMap<Object>();
	
	protected EncoderRegistry encoders = new EncoderRegistry();
	protected ParserRegistry parsers = new ParserRegistry();
	
	/**
	 * Creates a new instance with a <code>null</code> default URI.
	 */
	public HTTPBuilder() { 
		super();
		HttpParams defaultParams = new BasicHttpParams();
		defaultParams.setParameter( CookieSpecPNames.DATE_PATTERNS,
		        Arrays.asList("EEE, dd-MMM-yyyy HH:mm:ss z", 
		        		"EEE, dd MMM yyyy HH:mm:ss z") );
		this.client = this.createClient(defaultParams);
		this.setContentEncoding( ContentEncoding.Type.GZIP, 
				ContentEncoding.Type.DEFLATE );
	}
	
	/**
	 * Override this method in a subclass to customize creation of the 
	 * HttpClient instance.
	 * @param params
	 * @return
	 */
	protected AbstractHttpClient createClient( HttpParams params ) {
		return new DefaultHttpClient(params);
	}
{'fraction_non_alphanumeric': 0.10970045625867883, 'fraction_numerical': 0.0048270845731667, 'mean_word_length': 3.5955636584624733, 'pattern_counts': {'":': 0, '<': 103, '<?xml version=': 0, '>': 109, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5209424', 'n_tokens_mistral': 4483, 'n_tokens_neox': 4224, 'n_words': 1422}