You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by si...@apache.org on 2012/04/27 10:48:59 UTC

svn commit: r1331298 - in /lucene/dev/branches/lucene_solr_3_6: ./ solr/ solr/CHANGES.txt solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java

Author: siren
Date: Fri Apr 27 08:48:59 2012
New Revision: 1331298

URL: http://svn.apache.org/viewvc?rev=1331298&view=rev
Log:
SOLR-3375: backport charset bugfixes from trunk

Modified:
    lucene/dev/branches/lucene_solr_3_6/   (props changed)
    lucene/dev/branches/lucene_solr_3_6/solr/   (props changed)
    lucene/dev/branches/lucene_solr_3_6/solr/CHANGES.txt
    lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java
    lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java

Modified: lucene/dev/branches/lucene_solr_3_6/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_3_6/solr/CHANGES.txt?rev=1331298&r1=1331297&r2=1331298&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_3_6/solr/CHANGES.txt (original)
+++ lucene/dev/branches/lucene_solr_3_6/solr/CHANGES.txt Fri Apr 27 08:48:59 2012
@@ -31,6 +31,8 @@ Bug Fixes:
 * SOLR-3361: ReplicationHandler "maxNumberOfBackups" doesn't work if backups are triggered on commit
   (James Dyer, Tomas Fernandez Lobbe)
 
+* SOLR-3375: Fix charset problems with HttpSolrServer (Roger HÃ¥kansson, yonik, siren)
+
 ==================  3.6.0  ==================
 More information about this release, including any errata related to the 
 release notes, upgrade instructions, or other changes may be found online at:

Modified: lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java?rev=1331298&r1=1331297&r2=1331298&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java (original)
+++ lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrServer.java Fri Apr 27 08:48:59 2012
@@ -20,8 +20,11 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.ConnectException;
 import java.net.SocketTimeoutException;
+import java.nio.charset.Charset;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.InflaterInputStream;
 
@@ -34,7 +37,10 @@ import org.apache.http.HttpRequestInterc
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.HttpStatus;
+import org.apache.http.NameValuePair;
+import org.apache.http.NoHttpResponseException;
 import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpRequestBase;
@@ -45,6 +51,7 @@ import org.apache.http.conn.scheme.Schem
 import org.apache.http.conn.scheme.SchemeRegistry;
 import org.apache.http.conn.ssl.SSLSocketFactory;
 import org.apache.http.entity.HttpEntityWrapper;
+import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.entity.mime.FormBodyPart;
 import org.apache.http.entity.mime.HttpMultipartMode;
 import org.apache.http.entity.mime.MultipartEntity;
@@ -52,6 +59,8 @@ import org.apache.http.entity.mime.conte
 import org.apache.http.entity.mime.content.StringBody;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.EntityUtils;
@@ -135,6 +144,7 @@ public class HttpSolrServer extends Solr
   private int maxRetries = 0;
   
   private ThreadSafeClientConnManager ccm;
+  private boolean useMultiPartPost;
   
   /**
    * @param baseURL
@@ -212,9 +222,11 @@ public class HttpSolrServer extends Solr
   }
   
   public NamedList<Object> request(final SolrRequest request,
-      final ResponseParser processor) throws SolrServerException {
+      final ResponseParser processor) throws SolrServerException, IOException {
     HttpRequestBase method = null;
+    InputStream is = null;
     SolrParams params = request.getParams();
+    Collection<ContentStream> streams = requestWriter.getContentStreams(request);
     String path = requestWriter.getPath(request);
     if (path == null || !path.startsWith("/")) {
       path = DEFAULT_PATH;
@@ -237,55 +249,122 @@ public class HttpSolrServer extends Solr
     
     int tries = maxRetries + 1;
     try {
-      while (tries-- > 0) { // XXX this retry thing seems noop to me
-        Collection<ContentStream> streams = requestWriter
-            .getContentStreams(request);
-        // Note: since we aren't doing intermittent time keeping
+      while( tries-- > 0 ) {
+        // Note: since we aren't do intermittent time keeping
         // ourselves, the potential non-timeout latency could be as
         // much as tries-times (plus scheduling effects) the given
         // timeAllowed.
         try {
-          if (SolrRequest.METHOD.GET == request.getMethod()) {
-            if (streams != null) {
-              throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
-                  "GET can't send streams!");
+          if( SolrRequest.METHOD.GET == request.getMethod() ) {
+            if( streams != null ) {
+              throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "GET can't send streams!" );
             }
-            method = new HttpGet(baseUrl + path
-                + ClientUtils.toQueryString(params, false));
-          } else if (SolrRequest.METHOD.POST == request.getMethod()) {
+            method = new HttpGet( baseUrl + path + ClientUtils.toQueryString( params, false ) );
+          }
+          else if( SolrRequest.METHOD.POST == request.getMethod() ) {
+
             String url = baseUrl + path;
-            
-            MultipartEntity entity = new MultipartEntity(
-                HttpMultipartMode.BROWSER_COMPATIBLE);
-            
-            final HttpPost post = new HttpPost(url);
-            
-            final Iterator<String> iter = params.getParameterNamesIterator();
-            if (iter.hasNext()) {
-              
+            boolean isMultipart = ( streams != null && streams.size() > 1 );
+
+            LinkedList<NameValuePair> postParams = new LinkedList<NameValuePair>();
+            if (streams == null || isMultipart) {
+              HttpPost post = new HttpPost(url);
+              post.setHeader("Content-Charset", "UTF-8");
+              if (!this.useMultiPartPost && !isMultipart) {
+                post.addHeader("Content-Type",
+                    "application/x-www-form-urlencoded; charset=UTF-8");
+              }
+
+              List<FormBodyPart> parts = new LinkedList<FormBodyPart>();
+              Iterator<String> iter = params.getParameterNamesIterator();
               while (iter.hasNext()) {
-                final String name = iter.next();
-                final String[] vals = params.getParams(name);
+                String p = iter.next();
+                String[] vals = params.getParams(p);
                 if (vals != null) {
-                  for (String value : vals) {
-                    entity.addPart(name, new StringBody(value));
+                  for (String v : vals) {
+                    if (this.useMultiPartPost || isMultipart) {
+                      parts.add(new FormBodyPart(p, new StringBody(v, Charset.forName("UTF-8"))));
+                    } else {
+                      postParams.add(new BasicNameValuePair(p, v));
+                    }
                   }
                 }
               }
+
+              if (isMultipart) {
+                for (ContentStream content : streams) {
+                   parts.add(new FormBodyPart(content.getName(), new InputStreamBody(content.getStream(), content.getName())));
+                }
+              }
+              
+              if (parts.size() > 0) {
+                MultipartEntity entity = new MultipartEntity(HttpMultipartMode.STRICT);
+                for(FormBodyPart p: parts) {
+                  entity.addPart(p);
+                }
+                post.setEntity(entity);
+              } else {
+                //not using multipart
+                HttpEntity e;
+                post.setEntity(new UrlEncodedFormEntity(postParams, "UTF-8"));
+              }
+
+              method = post;
+            }
+            // It is has one stream, it is the post body, put the params in the URL
+            else {
+              String pstr = ClientUtils.toQueryString(params, false);
+              HttpPost post = new HttpPost(url + pstr);
+
+              // Single stream as body
+              // Using a loop just to get the first one
+              final ContentStream[] contentStream = new ContentStream[1];
+              for (ContentStream content : streams) {
+                contentStream[0] = content;
+                break;
+              }
+              if (contentStream[0] instanceof RequestWriter.LazyContentStream) {
+                post.setEntity(new InputStreamEntity(contentStream[0].getStream(), -1) {
+                  @Override
+                  public Header getContentType() {
+                    return new BasicHeader("Content-Type", contentStream[0].getContentType());
+                  }
+                  
+                  @Override
+                  public boolean isRepeatable() {
+                    return false;
+                  }
+                  
+                });
+              } else {
+                post.setEntity(new InputStreamEntity(contentStream[0].getStream(), -1) {
+                  @Override
+                  public Header getContentType() {
+                    return new BasicHeader("Content-Type", contentStream[0].getContentType());
+                  }
+                  
+                  @Override
+                  public boolean isRepeatable() {
+                    return false;
+                  }
+                });
+              }
+              method = post;
             }
-            addParts(streams, entity);
-            post.setEntity(entity);
-            method = post;
-          } else {
-            throw new SolrServerException("Unsupported method: "
-                + request.getMethod());
           }
-        } catch (RuntimeException r) {
+          else {
+            throw new SolrServerException("Unsupported method: "+request.getMethod() );
+          }
+        }
+        catch( NoHttpResponseException r ) {
+          method = null;
+          if(is != null) {
+            is.close();
+          }
           // If out of tries then just rethrow (as normal error).
-          if ((tries < 1)) {
+          if (tries < 1) {
             throw r;
           }
-          // log.warn( "Caught: " + r + ". Retrying..." );
         }
       }
     } catch (IOException ex) {
@@ -296,8 +375,6 @@ public class HttpSolrServer extends Solr
     method.getParams().setParameter(ClientPNames.HANDLE_REDIRECTS,
         followRedirects);
     method.addHeader("User-Agent", AGENT);
-    method.setHeader("Content-Charset", UTF_8);
-    method.setHeader("Accept-Charset", UTF_8);
     
     InputStream respBody = null;
     
@@ -370,16 +447,6 @@ public class HttpSolrServer extends Solr
     }
   }
   
-  private void addParts(Collection<ContentStream> streams,
-      MultipartEntity entity) throws IOException {
-    if (streams != null) {
-      for (ContentStream content : streams) {
-        entity.addPart(new FormBodyPart(CommonParams.STREAM_BODY,
-            new InputStreamBody(content.getStream(), "")));
-      }
-    }
-  }
-  
   // -------------------------------------------------------------------
   // -------------------------------------------------------------------
   

Modified: lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java?rev=1331298&r1=1331297&r2=1331298&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java (original)
+++ lucene/dev/branches/lucene_solr_3_6/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java Fri Apr 27 08:48:59 2012
@@ -46,6 +46,7 @@ import org.apache.solr.client.solrj.util
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.util.XML;
 import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.FacetParams;
 import org.junit.Test;
 
@@ -437,8 +438,12 @@ abstract public class SolrExampleTests e
     ContentStreamUpdateRequest up = new ContentStreamUpdateRequest("/update");
     up.addFile(getFile("solrj/docs1.xml")); // 2
     up.addFile(getFile("solrj/docs2.xml")); // 3
+    up.setParam("a", "\u1234");
+    up.setParam(CommonParams.HEADER_ECHO_PARAMS, CommonParams.EchoParamStyle.ALL.toString());
     up.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
     NamedList<Object> result = server.request(up);
+    Assert.assertEquals("\u1234",
+        ((NamedList)((NamedList) result.get("responseHeader")).get("params")).get("a"));
     assertNotNull("Couldn't upload xml files", result);
     rsp = server.query( new SolrQuery( "*:*") );
     Assert.assertEquals( 5 , rsp.getResults().getNumFound() );