I received HTTP PUTs like:
PUT /photo HTTP/1.1
X-Apple-AssetKey: F92F9B91-954E-4D63-BB9A-EEC771ADE6E8
X-Apple-Transition: Dissolve
Content-Length: 462848
User-Agent: MediaControl/1.0
X-Apple-Session-ID: 1bd6ceeb-fffd-456c-a09c-996053a7a08c
<HERE COMES THE JPEG DATA>
Trying to store it, ends up in im==null exception
.
Socket s = server.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String tag = br.readLine().split(" ")[1];
System.out.println(tag);
if (tag.contains("/photo")) {
while (!br.readLine().equals(""));
File file = new File("" + System.currentTimeMillis() + ".jpg");
InputStream is = (s.getInputStream());
BufferedImage bImageFromConvert = ImageIO.read(is);
ImageIO.write(bImageFromConvert, "jpg", file);
System.out.println(file);
}
br.close();
s.close();
So my idea was to strip off the header with the BufferedReader then reading the remaining (jpeg containing) InputStream, but I guess BufferedReader does not affect the offset of InputStream. So how can I skip the Header and write the jpeg?
I wouldn't recommend doing it this way*, but if you really like to do it the low-level way, the HTTP header part always ends with the character sequence "\r\n\r\n"
(\r\n
is referred to as CRLF in the spec). Whenever in doubt, read up on the HTTP 1.1 specification.
All you need to do, is to search for this pattern:
byte[] endOfHeader = "\r\n\r\n".getBytes(); // alt: getBytes(Charset.forName("ASCII"))
int endIndex = 0;
BufferedInputStream input = new BufferedInputStream(s.getInputStream());
input mark();
try {
int read;
while ((read = input.read()) != -1) {
if (the last four bytes match endOfHeader) { // Left as an exercise ;-)
break;
}
endIndex++;
}
}
finally {
input.reset();
}
// Now you have the end of header in endIndex
// You now have to re-read the header part using a character Reader
// (BufferedReader is fine, just make sure you have the correct encoding)
// but make sure read *exactly* until endIndex before attempting to read further.
// The rest of input can now be read using ImageIO or similar, as you like.
// PS: Don't forget that the content may be chunked or zipped during
// transfer-encoding. You might need to handle this, unless you also
// control the client sending the PUT request.
// PPS: I told you wouldn't recommend this ;-)
*) My preferred way would be to use an embedded Jetty instance, and create servlet to handle the PUT. With minimal setup and configuration, it starts very fast. It might sound overkill, but you save yourself some pain in the long run, I think.