On Tue, 2022-05-10 at 18:13 -0400, Skylos wrote:
> I'm communicating with an out of spec server which does not recognize
> "+"
> as a blank space in query strings - this was quite a problem as I am
> passing actual filenames which I don't control and which may have
> spaces in
> them!
> 
> The workaround I built was to copy format (and everything it calls)
> from
> URLEncodedUtils and augment to pass down the blankAsPlus value, which
> I
> then call explicitly by bypassing the built in encoder by sending in
> a raw
> encoded querystring as part of the original url string I use for my
> client
> retrieve/execution.
> 
> It turns out that this function:
> 
> private static String encodeFormFields (final String content, final
> Charset
> charset);
> 
> needs to have a 'false' as the ultimate argument in the call to this
> function:
> 
> private static String urlEncode(
> final String content,
> final Charset charset,
> final BitSet safechars,
> final boolean blankAsPlus);
> 
> There was apparently no consideration that this might be necessary
> outside
> this private context. It's okay. I totally understand. I also
> understand
> that you may not like the idea of being compatible with obviously out
> of
> spec servers. But - it is my philosophical assertion that as a
> library
> which may be used by many divers purposes, it is better to allow the
> user
> to do whatever he wants, rather than to be quite so opinionated about
> it as
> to make it impossible to bypass the blankAsPlus while encoding
> 
> My humble suggestion as thus - allow injection of blankAsPlus boolean
> external to the class.  (I didn't chase *all* the format
> dependencies, but
> would be easy enough to do with a refactor calc or simply add a
> compatibility signature)
> 
> (this one is in UrlEncodedFormEntity.java - conform with api change
> and
> compatibility constructor?  defer to you.)
> 
> -   public UrlEncodedFormEntity (
> -       final Iterable <? extends NameValuePair> parameters,
> -       final Charset charset) {
> -       super(URLEncodedUtils.format(parameters,
> -               charset != null ? charset :
> HTTP.DEF_CONTENT_CHARSET),
> -               ContentType.create(URLEncodedUtils.CONTENT_TYPE,
> charset));
> -   }
> +   public UrlEncodedFormEntity (
> +       final Iterable <? extends NameValuePair> parameters,
> +       final Charset charset) {
> +       super(URLEncodedUtils.format(parameters,
> +               charset != null ? charset :
> HTTP.DEF_CONTENT_CHARSET),
> +               ContentType.create(URLEncodedUtils.CONTENT_TYPE,
> charset),
> +               false);
> +   }
> +   public UrlEncodedFormEntity (
> +       final Iterable <? extends NameValuePair> parameters,
> +       final Charset charset,
> +       boolean blankAsPlus) {
> +       super(URLEncodedUtils.format(parameters,
> +               charset != null ? charset :
> HTTP.DEF_CONTENT_CHARSET),
> +               ContentType.create(URLEncodedUtils.CONTENT_TYPE,
> charset),
> +               blankAsPlus);
> +   }
> 
> 
> (this one is in URIBuilder.java - conform to api change - consider
> also
> adding mode/flag in builder to turn this on/off? (I really like this
> idea))
> 
>      public static String encodeUrlForm(final List<NameValuePair>
> params) {
> -        return format(params, Consts.UTF_8);
> +        return format(params, Consts.UTF_8, false);
>      }
> 
> (These are all in URLEncodedUtils.java - pass the value down in and
> default
> on the public level with the old api.)
> 
> -    public static String format(
> -          final Iterable<? extends NameValuePair> parameters,
> -          final Charset charset) {
> -        return format(parameters, '&', charset);
> +    public static String format(
> +          final Iterable<? extends NameValuePair> parameters,
> +          final Charset charset) {
> +        return format(parameters, '&', charset, false);
> +    }
> +    public static String format(
> +          final Iterable<? extends NameValuePair> parameters,
> +          final Charset charset,
> +          boolean blankAsPlus) {
> +        return format(parameters, '&', charset, blankAsPlus);
>      }
> 
> -    public static String format(
> -          final Iterable<? extends NameValuePair> parameters,
> -          final char parameterSeparator,
> -          final Charset charset) {
> +    public static String format(
> +          final Iterable<? extends NameValuePair> parameters,
> +          final char parameterSeparator,
> +          final Charset charset,
> +          boolean blankAsPlus) {
>          Args.notNull(parameters, "Parameters");
>          final StringBuilder result = new StringBuilder();
>          for (final NameValuePair parameter : parameters) {
> -            final String encodedName =
> encodeFormFields(parameter.getName(), charset);
> -            final String encodedValue =
> encodeFormFields(parameter.getValue(), charset);
> +            final String encodedName =
> encodeFormFields(parameter.getName(), charset, blankAsPlus);
> +            final String encodedValue =
> encodeFormFields(parameter.getValue(), charset, blankAsPlus);
>              if (result.length() > 0) {
>                  result.append(parameterSeparator);
>              }
> 
> (And finally encodeFormFields itself.)
> 
> -    private static String encodeFormFields (final String content,
> final
> Charset charset) {
> +    private static String encodeFormFields(final String content,
> final
> Charset charset, boolean blankAsPlus) {
>          if (content == null) {
>              return null;
>          }
> -        return urlEncode(content, charset != null ? charset :
> Consts.UTF_8, wwwFormUrlSafe(), false);
> +        return urlEncode(content, charset != null ? charset :
> Consts.UTF_8, wwwFormUrlSafe(), blankAsPlus);
>      }
> 
> If you'd like me to submit a pull request on this, point me to the
> code
> repo you're using and I'll be happy to generate one.
> 
> 

As of version 5.0 HttpClient no longer uses the old `plus as blank`
encoding scheme.

Project code repositories can be found at the GitHub

https://github.com/apache/httpcomponents-core
https://github.com/apache/httpcomponents-client

Oleg



---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org

Reply via email to