Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

byte[] content is not repeatable? #507

Open
johanhaleby opened this issue Jul 21, 2015 · 7 comments
Open

byte[] content is not repeatable? #507

johanhaleby opened this issue Jul 21, 2015 · 7 comments

Comments

@johanhaleby
Copy link
Collaborator

From normanwalsh on September 03, 2014 23:13:52

If you attempt to post a byte[] body to an endpoint that performs digest authentication, you get a long stack trace that ends near

org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.

Why isn't a byte[] array repeatable?

Original issue: http://code.google.com/p/rest-assured/issues/detail?id=352

@pdurbin
Copy link

pdurbin commented Dec 8, 2015

I believe that this issue is not just limited to digest auth. I'm seeing the same problem with basic auth as well: .auth().basic(username, password)

As a workaround I'm shelling out to curl for now, but I'd much rather use rather use rest-assured. Please see uploadZipFile vs. uploadZipFileWithCurl at https://github.com/IQSS/dataverse/blob/v4.2.1/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java#L851

pdurbin added a commit to IQSS/dataverse that referenced this issue Dec 8, 2015
@pdurbin
Copy link

pdurbin commented Dec 8, 2015

@johanhaleby thanks for the clue about auth. I just added "preemptive" to my basic auth call, changing...

.auth().basic(username, password)

... to ...

.auth().preemptive.basic(username, password)

I'm not sure why this works but here's the commit I just made where I switched from .multiPart(new File(pathToFileName)) to .body(myArrayOfBytes): IQSS/dataverse@3d2ac41

Here also is the stacktrace where I switched to bytes but had not yet added "preemptive" to auth that shows org.apache.http.client.ClientProtocolException and Caused by: org.apache.http.client.NonRepeatableRequestException: Cannot retry request with a non-repeatable request entity.: stacktrace.txt

See also https://github.com/jayway/rest-assured/wiki/Usage#preemptive-basic-authentication

@johanhaleby
Copy link
Collaborator Author

@pdurbin Hmm not sure if I gave you the clue about auth :) When did I do that?

It's very interesting that it works when you switch to preemptive basic auth. I don't know why it would work better with preemptive basic auth.. Preemptive basic auth just pre-populates a header with the authentication details instead of waiting for the server to be challenged. But perhaps that's also the answer. Could it be that the server rejects the multipart upload if there are no credentials attached to the request?! But if so the error of NonRepeatableRequestException seem quite confusing.

@danielFesenmeyer
Copy link

I agree with @pdurbin: NonRepeatableRequestException is very confusing. Imo, this is a bug. In my scenario, posting JSON content works fine, but a byte array does not. This does not make sense.

@anton-kapelyushok
Copy link

Why should requests be repeatable in the first place?

@chairbender
Copy link

Just for anyone else finding this by googling, I found that I had this issue when the body was anything other than String, but only when I was using restassured in combination with com.github.dzieciou.testing:curl-logger, and it even happened when using preemptive basic auth.

My solution to the issue was to add an interceptor which wraps the entity in a buffered http entity, which makes it repeatable. This is acceptable to me for test cases but may not be great for other scenarios. You can do this like so (add the returned config to your restassured request).

HttpClientConfig.httpClientConfig()
        .httpClientFactory(
            () -> {
              HttpRequestInterceptor reqIntercept = (req, context) -> {
                if (req instanceof HttpEntityEnclosingRequest)
                {
                  HttpEntityEnclosingRequest erq = (HttpEntityEnclosingRequest) req;
                  if (erq.getEntity() != null) {
                    erq.setEntity(new BufferedHttpEntity(erq.getEntity()));
                  }
                }
              };
              client.addRequestInterceptor(reqIntercept);
              return client;
            });

@MohanscodeHub
Copy link

Hi ,

I am trying something similar , I am trying to post a zip file to artifactory . Can anyone please advise how do I config my request to send ZIP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants