i am writing a small java client that uses the Azure Service Management API to create a new VM Deployment on Azure.
i keep getting bad requests responses like these:
17/07/2012 18:26:37 com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client out-bound request
1 > POST https://management.core.windows.net/my-subscription-id/services/hostedservices/myservice/deployments
1 > x-ms-version: 2012-03-01
1 > Content-Type: application/xml
<Deployment xmlns="http://schemas.microsoft.com/windowsazure">
<Name>mynametest</Name>
<DeploymentSlot>Staging</DeploymentSlot>
<Label>mynamelabel</Label>
<RoleList>
<Role>
<RoleName>mynamerolename</RoleName>
<RoleType>PersistentVMRole</RoleType>
<ConfigurationSets>
<ConfigurationSet>
<ConfigurationSetType>LinuxProvisioningConfiguration</ConfigurationSetType>
<HostName>myunamehost</HostName>
<UserName>myname</UserName>
<UserPassword>password</UserPassword>
</ConfigurationSet>
</ConfigurationSets>
<OSVirtualHardDisk>
<SourceImageName>CANONICAL__Canonical-Ubuntu-12-04-amd64-server-20120528.1.3-en-us-30GB.vhd</SourceImageName>
</OSVirtualHardDisk>
</Role>
</RoleList>
</Deployment>
17/07/2012 18:26:38 com.sun.jersey.api.client.filter.LoggingFilter log
INFO: 1 * Client in-bound response
1 < 400
1 < x-ms-request-id: c622e270c5934cb493f76790b7d2c49d
1 < Date: Tue, 17 Jul 2012 15:27:26 GMT
1 < Content-Length: 275
1 < Content-Type: application/xml; charset=utf-8
1 < Server: 6.0.6002.18488 (rd_rdfe_stable.120710-1331) Microsoft-HTTPAPI/2.0
1 <
<Error xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Code>BadRequest</Code><Message>No target URI is specified for the image CANONICAL__Canonical-Ubuntu-12-04-amd64-server-20120528.1.3-en-us-30GB.vhd.</Message></Error>
it looks like the docs from azure are buggy: http://msdn.microsoft.com/en-us/library/windowsazure/jj157194
anyone has tried this before? i dont understand what does 'target URI' mean...
the image name is taken from the public gallery of images on azure.
any help, any help at all, will be highly appreciated.
thanks
Your xml have some bad configuration i.e. DeploymentSlot etc and I also believe the error is coming because you do not have all required settings in your XML. Following is the working one for Linux Gallery image:
<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Name>mydeploymentname</Name>
<Label>mydeploymentlabel</Label>
<RoleList>
<Role>
<RoleName>mylinuxvm2012</RoleName>
<RoleType>PersistentVMRole</RoleType>
<ConfigurationSets>
<ConfigurationSet>
<ConfigurationSetType>LinuxProvisioningConfiguration<ConfigurationSetType>
<HostName>host-name-for-the-vm</HostName>
<UserName>new-user-name</UserName>
<UserPassword>password-for-the-new-user</UserPassword>
<DisableSshPasswordAuthentication>true|false</DisableSshPasswordAuthentication>
<SSH>
<PublicKeys>
<PublicKey>
<FingerPrint>******add_here******</FingerPrint>
<Path>****SSH-public-key-storage-location**********</Path>
</PublicKey>
</PublicKeys>
<KeyPairs>
<KeyPair>
<FingerPrint>************certificate-fingerprint*************</FinguerPrint>
<Path>*************SSH-public-key-storage-location*************</Path>
</KeyPair>
</KeyPairs>
</SSH>
</ConfigurationSet>
<OSVirtualHardDisk>
<HostCaching>ReadWrite</HostCaching>
<DiskLabel>myosdisklabel</DiskLabel>
<DiskName>myazurelinuxvm</DiskName>
<MediaLink>https://_yourstoragename_.blob.core.windows.net/vhds/_your_VHD_NAME_.vhd</MediaLink>
<SourceImageName>CANONICAL__Canonical-Ubuntu-12-04-amd64-server-20120528.1.3-en-us-30GB.vhd</SourceImageName>
</OSVirtualHardDisk>
<RoleSize>_ExtraSmall|Small|Medium|Large|ExtraLarge_</RoleSize>
</Role>
</RoleList>
Related
I have a small demo to play with customized status code.
The interesting part is the request will always hang there if the status is below 200, like 105, 199, etc. But works for any status greater than 200, like 209, 789 etc.
Http status code registry, refer to https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
Spring boot: 1.5.4.RELEASE with embedded tomcat
Java: 8
Controller:
#RestController
public class DemoController {
#GetMapping("/hello")
public ResponseEntity get() {
return ResponseEntity.status(105).build();
}
}
Can anyone give me a clear explanation?
I create a gist at here: https://gist.github.com/pengisgood/dbea1fcdc45c2bb5809871c7f020b800
Update:
I also create a small demo to reproduce it at here:
https://github.com/pengisgood/springboot-customize-status-code
Update:
After I run curl -v localhost:8080/hello, I can see the status, but the response doesn't finish. Refer to the gif below:
I also ran into this issue and found that it is not Spring that creates this behavior. It is Tomcat.
curl -v --header "Expect: 100-continue" http://localhost:8080
Calling any configured endpoint like this will return an extra response code that doesn't terminate the request.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0*
Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.56.1
> Accept: */*
> Expect: 100-continue
>
< HTTP/1.1 100
< HTTP/1.1 200
< Set-Cookie: JSESSIONID=9355141A10CF546E9A9A43F5A5C0B1A4; Path=/; HttpOnly
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 58
< Date: Tue, 31 Jul 2018 17:27:52 GMT
<
{ [58 bytes data]
100 58 100 58 0 0 58 0 0:00:01 --:--:-- 0:00:01 82<html>
<body>
<h2>Hello Heroku!</h2>
</body>
</html>
* Connection #0 to host localhost left intact
note the HTTP/1.1 100
This response came from this project https://devcenter.heroku.com/articles/create-a-java-web-application-using-embedded-tomcat which doesn't have spring. If I modify the HelloServlet to include a response code of 100 it just hangs.
Looking deeper:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3
The specification makes it clear that the 100 response is supposed to happen in the same request. The reason it hangs is because it is expecting the client to respond with the content of the request.
Looking at the wiki for other 1XX response codes, it appears to also be true that some information is returned without closing the request. My guess is that Tomcat expects all 1xx response codes to act in this manner.
As far as I can tell the Spring DispacherServlet is handling the different return codes in exactly the same way. I think what's happening is curl is just leaving the connection open because the response is in the 1xx range.
This article provides a good primer on status codes. This sentence in particular is relevant:
100–199 Codes in the 100s are informational, indicating that the client should respond with some other action.
If you run curl with --trace you'll see that the 105 response does actually arrive:
curl -v -trace http://localhost:8080/hello
Trying ::1...
TCP_NODELAY set
Connected to localhost (::1) port 8080 (#0)
> GET /hello HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 105
< Date: Tue, 19 Sep 2017 18:07:04 GMT
^C
So what I think is happening is the response is returned, the client should respond with some other action (but doesn't) so it looks like the thing has hung.
Probably the real question here is why are you trying to return a 105 status and what do you expect to happen?
For some reason the previously working code stopped working and server started to respond with 416.
Here are the logs of HTTP client during failing interaction:
-------------- REQUEST --------------
GET https://www.googleapis.com/drive/v3/files/0B02Nopv3SQOvOVNKaDIwTEZ3MHd?alt=media
Accept-Encoding: gzip
Authorization: <Not Logged>
Range: bytes=0-33554431
User-Agent: My app Google-API-Java-Client Google-HTTP-Java-Client/1.22.0 (gzip)
-------------- RESPONSE --------------
HTTP/1.1 416 Requested range not satisfiable
Alt-Svc: quic=":443"; ma=2592000; v="39,38,37,35"
Server: UploadServer
Cache-Control: private, max-age=0
Content-Range: bytes */0
X-GUploader-UploadID: AEnB2UqBx9B09Lnr8tG761gdoz3DkhHSNO_OzHh1LkU6B2908v17rnBGQZSNW4ZVTjbRdFtvPWWIqZGdtSrTo6ZWN7YW9nxf6d
Vary: X-Origin
Vary: Origin
Expires: Mon, 11 Sep 2017 15:23:20 GMT
Content-Length: 225
Date: Mon, 11 Sep 2017 15:23:20 GMT
Content-Type: application/json; charset=UTF-8
I was trying to download a file which is around 200000 bytes, so I thought meaning of "chuck size" changed somewhere, so it could not give 33554431 bytes of a 282177 byte file. Tried changing that to a smaller value, but no success.
Drive.Files.Get get = drive.files().get(file.getId())
MediaHttpDownloader downloader = get.getMediaHttpDownloader()
downloader.directDownloadEnabled = false
localFile.newOutputStream()
get.executeMediaAndDownloadTo(stream)
Direct download does not work either, it just downloads "0" bytes.
Does anyone know how to overcome this issue?
416 Range Not
Satisfiable
error means the server is not able to serve the requested ranges. The
most likely reason is that the document doesn't contain such ranges,
or that the Range header value, though syntactically correct, doesn't
make sense.
One of the resolutions that may provide from this forum is to:
Add "Accept-Ranges: none" to our response headers.
It appeared to be a web interface when using Firefox. It uploaded "empty" files in certain cases.
https://productforums.google.com/forum/#!topic/drive/S03wEknc75g;context-place=forum/drive
The http file example under test:
https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example/http/file
I compiled the above example with netty-4.1.0.beta8.
My test result:
$ ab -k -n 2 -c 1 -v 6 http://127.0.0.1:8080/test.sh
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)...INFO: POST header ==
---
GET /test.sh HTTP/1.0
Connection: Keep-Alive
Host: 127.0.0.1:8080
User-Agent: ApacheBench/2.3
Accept: */*
---
LOG: header received:
HTTP/1.1 200 OK
content-length: 462
content-type: application/octet-stream
date: Fri, 26 Feb 2016 06:34:52 GMT
expires: Fri, 26 Feb 2016 06:35:52 GMT
cache-control: private, max-age=60
last-modified: Fri, 19 Feb 2016 02:35:40 GMT
connection: keep-alive
LOG: Response code = 200
LOG: header received:
**MY TEST.SH CONTENT**
WARNING: Response code not 2xx (500)
apr_poll: The timeout specified has expired (70007)
Total of 1 requests completed
It seemed that my test.sh content is considered to be the second request's headers.
My further test:
$ ab -k -n 1 -c 1 -v 6 http://127.0.0.1:8080/test.sh
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)...INFO: POST header ==
---
GET /test.sh HTTP/1.0
Connection: Keep-Alive
Host: 127.0.0.1:8080
User-Agent: ApacheBench/2.3
Accept: */*
---
LOG: header received:
HTTP/1.1 200 OK
content-length: 462
content-type: application/octet-stream
date: Fri, 26 Feb 2016 06:39:02 GMT
expires: Fri, 26 Feb 2016 06:40:02 GMT
cache-control: private, max-age=60
last-modified: Fri, 19 Feb 2016 02:35:40 GMT
connection: keep-alive
LOG: Response code = 200
..done
Server Software:
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /test.sh
Document Length: 0 bytes
Concurrency Level: 1
Time taken for tests: 0.005 seconds
Complete requests: 1
Failed requests: 0
Write errors: 0
Keep-Alive requests: 1
Total transferred: 263 bytes
HTML transferred: 0 bytes
Requests per second: 209.25 [#/sec] (mean)
Time per request: 4.779 [ms] (mean)
Time per request: 4.779 [ms] (mean, across all concurrent requests)
Transfer rate: 53.74 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 5 5 0.0 5 5
Waiting: 5 5 0.0 5 5
Total: 5 5 0.0 5 5
You can see the document length is 0 byte.
I run similar commands against www.google.com and it works fine.
Could you please help on this? Thanks in advance.
This is a bug in ApacheBench.
ApacheBench does not follow the http specifications fully, and assumes headers have a certain capitalization. Because the headers returned by the netty application doesn't have the character case ApacheBench expects, it assumes a default of 0 bytes for the content length.
Http specification 4.2:
HTTP header fields, which include general-header (section 4.5),
request-header (section 5.3), response-header (section 6.2), and
entity-header (section 7.1) fields, follow the same generic format as
that given in Section 3.1 of RFC 822 [9]. Each header field consists
of a name followed by a colon (":") and the field value. Field names
are case-insensitive. The field value MAY be preceded by any amount of
LWS, though a single SP is preferred. Header fields can be extended
over multiple lines by preceding each extra line with at least one SP
or HT. Applications ought to follow "common form", where one is known
or indicated, when generating HTTP constructs, since there might exist
some implementations that fail to accept anything beyond the common forms.
Because the keep-alive switch of ApacheBench forces it to assume the server supports keep alive, it doesn't detect a "missing" header for the keep alive packet.
This problem if however something that should be solved in ApacheBench, as it is a bug in that application that causes it to miss the proper content-length.
I building a REST-API with restlet to serve a mp3 file. But the File is created and served at the same time. More informations about that here.
It work perfectly but I only tested it in a desktop environment. When I fired up my iPad to test the API, it starts playing the File but after some seconds it stops, send a new Request and starts playing the File from the beginning.
After some researcher I find out that the iPad sends a Partial Request and therefore expects a partial response.
So I modified the Response-Header to fulfill the requirements.
I use curl to test the API :
curl -v -r 0-1 http://localhost:12345/api/path/file.mp3
Request-Header
GET /api/path/file.mp3 HTTP/1.1
Range: bytes=0-1
User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
Host: localhost:12345
Accept: */*
Response-Header
HTTP/1.1 206 Partial Content
Date: Tue, 29 Oct 2013 12:18:11 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.1.0
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Length: 2
Content-Range: bytes 0-1/19601021
Content-Type: audio/mpeg; charset=UTF-8
Expires: Tue, 29 Oct 2013 12:18:07 GMT
Last-Modified: Tue, 29 Oct 2013 12:18:07 GMT
Error-Message
But there is no Data that comes back from the server. Curl keeps the connection open to the server and the iPad sends a new Request.
When I shut the server down curl gives me:
transfer closed with 1 bytes remaining to read
Closing connection #0
curl: (18) transfer closed with 1 bytes remaining to read
Code
And here is the code I use to return the data. As you can see, this method is just for testing and should always return 2 bytes.
private InputRepresentation rangeGetRequest() throws IOException {
final byte[] bytes = new byte[2];
bytes[0] = 68;
bytes[1] = 68;
final InputRepresentation inputRepresentation = new InputRepresentation(new ByteArrayInputStream(bytes), MediaType.AUDIO_MPEG);
return inputRepresentation;
}
I have no idea what to do. I try to write my own InputStream that returns the 2 bytes, but without success.
Or is the InputRepresentation not suitable for this area of application?
Thanks in advance
Ok, I solved the problem, it was a stupid mistake.
To modify the response-header, I used
getResponse().setEntity(new StringRepresentation(" "));
getResponse().getEntity().setSize(19601021);
getResponse().getEntity().setRange(new Range(0, 2));
getResponse().getEntity().setModificationDate(new Date());
getResponse().getEntity().setExpirationDate(new Date());
getResponse().getEntity().setMediaType(MediaType.AUDIO_MPEG);
The first line was a relic from an old test. If I just use the actual InputRepresentation that holds the two bytes and it work just fine.
What do I learn from that, first tidy up your code, then ask questions ^^
I have a client who is attempting to use our .Net WebService with their Java environment. They're using 'javax.xml.soap.*' which requires a namespace prefix. These same namespace prefixes cause parsing exceptions on our end.
SoapServerMessage.Exception : "Server was unable to read request."
We are using 'System.Web.Services.WebService'
Here is a request they are trying to pass through:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Header>
<ct:CredentialsSoapHeader xmlns:ct="http://ourwebsite.com/webservices/"
xsi:type="WebServiceKeyCredentials">
<Key>demoKey</Key>
<Password>demoPassword</Password>
</ct:CredentialsSoapHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ct1:GetUserID xmlns:ct1="http://ourwebsite.com/webservices/">
<EmailAddress>example#somewebsite.com</EmailAddress>
</ct1:GetUserID>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The generated response:
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/xml; charset=utf-8
ETag: ""
Server: Microsoft-IIS/7.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 17 Jan 2012 19:28:20 GMT
Content-Length: 0
As soon as I strip away the namespace prefix, the request works fine. I'm not very familiar with this system but I will try to provide any information as needed.
Thank you in advance for any help that can be provided!