Testing of Raw HTTP post in java, 400 Bad Request - java

I have developed a raw http post in java. I am trying to post a file to the post request dump website http://www.posttestserver.com/. But it shows and error
400 Bad Request. Pleas let me know what need to be done to avoid this error.
In this code , output => Stream to write on server.
filename -> path on server, here filename is initated to post.php
output.println("POST"+" "+filename+" HTTP/1.1\r");
//output.println("Content-Length: "+data.length());
output.println("Content-Type: multipart/form-data, boundary=AaB03x\r");
output.println("Content-length: 100\r");
//As http1.1 is by default keep-alive , close the connection explicitly
output.println("Connection: Close");
// blank line
output.println();
output.println("--AaB03x");
output.print(
"--AaB03x Content-Disposition: form-data; name=\"fileID\"; filename=\"temp.txt\" Content-Type: text/plain "
+"/nHello How are you?"
+ "/n--AaB03x--");
output.flush();
Error is
HTTP/1.1 400 Bad Request
Date: Wed, 18 Mar 2015 02:22:00 GMT
Server: Apache
Vary: Accept-Encoding
Content-Length: 226
Connection: close
Content-Type: text/html; charset=iso-8859-1
400 Bad Request
Bad Request
Your browser sent a request that this server could not understand.

This might be the issue of Content type. Server is expecting a request having header of content type text/HTML but your request content type is multipart/form data.

Related

Get the raw http request/response message in java

I want the raw http request and response when sending an http request using java.
is there any way to do it without writing it manually? maybe adding tee with InputStream in the middle to capture it? or other solution?
i am currently using java.net.http library:
HttpRequest httpsRequest = getHttpsRequest(url, parameters, method, headers);
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> httpResponse = client.send(httpsRequest,HttpResponse.BodyHandlers.ofString(UTF_8));
String rawHttpMessage = ?
raw http message for example:
HTTP/1.1 200 OK
Date: Sun, 10 Oct 2010 23:26:07 GMT
Server: Apache/2.2.8 (Ubuntu) mod_ssl/2.2.8 OpenSSL/0.9.8g
Last-Modified: Sun, 26 Sep 2010 22:04:35 GMT
ETag: "45b6-834-49130cc1182c0"
Accept-Ranges: bytes
Content-Length: 12
Connection: close
Content-Type: text/html
Hello world!
request and response http message

Encrypted file name on download and not in expected language i.e. Arabic

I am trying to download file whose name is in Arabic language. Content of file is in arabic but name gets encrypted on download.
responseBuilder.header("Content-Disposition",
"attachment; filename=\"" + fileName + "\"; filename*=utf-8''" + URLEncoder
.encode(fileName, "UTF-8"));
fileName at this point is in Arabic language but on browser's response Header fileName gets changed to something else like E1-(E1-(.txt
Http Response Header:
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 10
Content-encoding: gzip
Connection: keep-alive
Cache-Control: private
Content-Disposition: attachment; filename="E1-(E1-(.txt.txt";
filename*=utf-8''%D9%85%D8%B1%D8%AD%D8%A8%D8%A7.txt
Expires: Mon, 26 Jul 1997 05:00:00 GMT
X-Backend: supra-prod-pdx-ff4d74bff-7srf7
X-Content-Type-Options: nosniff
X-Robots-Tag: noindex
X-Slack-Meta: proxy
Thank you in advance.
OKay, so at the UI side one can achieve this.
In the Response Header, fileName* provide the encoded value and at the UI end decode the value using following JS method:
remove utf8'' from the string, so you'll get the actual file name.
window.decodeURIComponent(t.substring(t.lastIndexOf('\'')+1,t.length));

POST request to a REST server

So, I'm trying to create a simple (and I mean simple) POST request. Here is the class on the server-side.
#Stateless
#Path("cards")
public class CardsFacadeREST extends AbstractFacade<Cards> {
#POST
#Path("test")
#Consumes({"text/plain"})
public void createTestCard() {
Cards card = new Cards();
card.setName("Test Card");
super.create(card);
}
#GET
#Path("count")
#Produces("text/plain")
public String countREST() {
return String.valueOf(super.count());
}
}
The GET method works just fine, but the POST method isn't working for me. I'm using Chrome's Advanced Rest Client.
The URL is http://localhost:8080/dc-rest/webresources/cards/test
The type is POST
My header is like so: Content-Type: text/plain
And that's it.
I keep getting a "400: Bad Request. The request sent by the client was syntactically incorrect."
When I open the response in the JSON window, all it says is "Unexpected token <"
Here are the request headers if that makes any difference.
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.103 Safari/537.36
Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
Content-Type: text/plain
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: JSESSIONID=f4c746a32b46244d422800192f04; treeForm_tree- hi=treeForm:tree:applications
Body is empty.
And the response:
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)
Server: GlassFish Server Open Source Edition 4.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Allow: GET,DELETE,OPTIONS,PUT,POST
Access-Control-Allow-Headers: content-type
Content-Language:
Content-Type: text/html Date: Thu, 11 Feb 2016 20:48:12 GMT
Connection: close Content-Length: 1105
Body:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>GlassFish Server Open Source Edition 4.0 - Error report</title><style type="text/css"><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 400 - Bad Request</h1><hr/><p><b>type</b> Status report</p><p><b>message</b>Bad Request</p><p><b>description</b>The request sent by the client was syntactically incorrect.</p><hr/><h3>GlassFish Server Open Source Edition 4.0 </h3></body></html>
The 400-Bad request response is likely because the server has expressed that it expects a specific content type
#Consumes({"text/plain"}
However the client is not indicating that the post body is of this type.
To solve this, make sure that the POST request from your client contains the following HTTP header:
Content-Type: text/plain
Or, perhaps it is the case that you are not POSTing plain text and you intend to POST XML or JSON. Whatever the intended type, you just need to make sure the client and server are in agreement about it.
If an HTTP request has a body, it must have either Content-Length or Transfer-Encoding header.
With neither, the request has no body -- not even a body of length 0. If you want to send an empty body, the request should have header Content-Length: 0.
There is a semantic difference between having no body and having an empty body. The server apparently rejects the POST request with no body. (Though the request is actually syntactically valid according to RFC)
Actually, this part is not quite clear (discussion thread (don't read)). And some implementations set Content-Length: 0 for GET requests; some implementations omit Content-Length: 0 for empty POST bodies; both are wrong... Sometimes they work sometimes they don't. Welcome to the chaotic world of HTTP.
I hate it when this happens. It was something else entirely, my persistence bean is messed up. When I commented out "super.create(card)" in my POST method, everything worked (request body or no).
Still have no idea why that resulted in "400: Bad Request. The request sent by the client was syntactically incorrect."
Seems like I have another problem to figure out, but this one at least is solved.
Thank y'all for helping!

OneDrive API download in parts

I am currently trying to develop a Java based app to access OneDrive.
Today i tried to implement the download as described here: https://dev.onedrive.com/items/download.htm
I wanted to use the range parameter, to offer the user the capability to pause large downloads. But no matter how i send the parameter be at within the HTTP-Request header or in the URL as a GET-Parameter it will always send me the complete file.
Things i tried so far:
https:/ /api.onedrive.com/v1.0/drive/items/***/content?range=0-8388607
(OAuth via HTTP header)
https:/ /api.onedrive.com/v1.0/drive/items/***/content:
Header: Authorization: ***
range: 0-8388607
https:/ /api.onedrive.com/v1.0/drive/items/***/content:
Header: Authorization: ***
range: bytes=0-8388607
I also tried Content-Range and various variations on lower and upper case without success. Any reason why this dose not work?
PS.:
The links a broken because i am using a new account that only allows 2 links per post, I am aware that ther is a space between the two // in my post ;)
Requesting the range of the file is supported. You might want to use fiddler or some other tool to see if the original headers are being passed after the 302 redirect is performed. Below are the HTTP requests and responses when I provide the range header which is being passed on after the 302 redirect occurs. You'll notice that a HTTP 206 partial content response is returned. Additionally, to resume a download, you can use "Range: bytes=1025-" or whatever the last byte received was. I hope that helps.
GET https://api.onedrive.com/v1.0/drive/items/item-id/content HTTP/1.1
Authorization: Bearer
Range: bytes=0-1024
Host: api.onedrive.com
HTTP/1.1 302 Found
Content-Length: 0
Location: https://kplnyq.dm2302.livefilestore.com/edited_location
Other headers removed
GET https://kplnyq.dm2302.livefilestore.com/edited_location
Range: bytes=0-1024
Host: kplnyq.dm2302.livefilestore.com
HTTP/1.1 206 Partial Content
Cache-Control: public
Content-Length: 1025
Content-Type: audio/mpeg
Content-Location: https://kplnyq.dm2302.livefilestore.com/edited_location
Content-Range: bytes 0-1024/4842585
Expires: Tue, 11 Aug 2015 21:34:52 GMT
Last-Modified: Mon, 12 Dec 2011 21:33:41 GMT
Accept-Ranges: bytes
Server: Microsoft-HTTPAPI/2.0
Other headers removed

App Engine HTTP Status Code message

I found an inconsistency between Java's dev_appserver and the live App Engine server.
On my local development server I have a Servlet which returns:
return response.sendError(response.SC_BAD_REQUEST, "Please log in to comment");
When I access the page I get back a Status Code message in the header which is:
Status Code:400 Please log in to comment
The issue comes when I deploy this to App Engine. When accessing that same servlet I get this "Bad Request" instead of "Please log in to comment":
Status Code:400 Bad Request
The Please log in to comment Status Code message appears in the content HTML, but not in the header as it does in the development environment.
Why is this?
Edit
Here's the curl -vvvv traces for both dev_appserver and production:
dev_appserver curl trace:
> POST /add-comment HTTP/1.1
> User-Agent: Mozilla/4.0
> Host: localhost:8080
> Accept: */*
> Content-Length: 9
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 400 Please log in to comment
< Content-Type: text/html; charset=iso-8859-1
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Length: 1406
< Server: Jetty(6.1.x)
Production curl trace:
> POST /add-comment HTTP/1.1
> User-Agent: Mozilla/4.0
> Host: www.xxx.org
> Accept: */*
> Content-Length: 9
> Content-Type: application/x-www-form-urlencoded
>
< HTTP/1.1 400 Bad Request
< Content-Type: text/html; charset=utf-8
< Vary: Accept-Encoding
< Date: Thu, 18 Aug 2011 14:04:26 GMT
< Server: Google Frontend
< Cache-Control: private
< Transfer-Encoding: chunked
I would say the prod system is the correct implementation. The javadocs for sendError() say:
Sends an error response to the client using the specified status. The
server defaults to creating the response to look like an
HTML-formatted server error page containing the specified message,
setting the content type to "text/html", leaving cookies and other
headers unmodified. If an error-page declaration has been made for the
web application corresponding to the status code passed in, it will be
served back in preference to the suggested msg parameter.
If the response has already been committed, this method throws an
IllegalStateException. After using this method, the response should be
considered to be committed and should not be written to.
I highlighted a part. This says it just returns a html page with the message when possible. It doesn't say it uses it in the HTTP Status code (which I personally haven't seen anywhere as well :()
It isn't specifically a problem with sendError. The setStatus method will behave the same way. Under normal Java, both sendError and setStatus do set the status description. The issue is that the production App Engine server always sets the status description to the standard description for each code.

Categories