/* * Copyright (C) 2025 Ignite Realtime Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.util; import org.apache.http.HttpStatus; import org.dom4j.Element; import org.jivesoftware.openfire.vcard.VCardManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Base64; /** * Servlet that outputs the photo that is part of a user's VCard as an image.
*
* @author Guus der Kinderen
*/
public class VCardPhotoServlet extends HttpServlet
{
private static final Logger Log = LoggerFactory.getLogger(VCardPhotoServlet.class);
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException
{
final String username = request.getParameter("username");
// Input validation.
if (username == null || username.isEmpty()) {
response.sendError(HttpStatus.SC_BAD_REQUEST, "Missing 'username' parameter.");
return;
}
Log.debug("Request for vCard Photo of '{}'", username);
// Check if there's a VCard for that user.
final Element vCardElement = VCardManager.getInstance().getVCard(username);
if (vCardElement == null) {
Log.trace("No vCard for '{}'", username);
response.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
if (vCardElement.element( "PHOTO") == null) {
Log.trace("No photo in vCard for '{}'", username);
response.setStatus(HttpStatus.SC_NO_CONTENT);
return; }
if (vCardElement.element( "PHOTO").element( "BINVAL") == null || vCardElement.element( "PHOTO").element( "TYPE") == null) {
Log.trace("No vCard binval or type for '{}'", username);
response.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
final Element element = vCardElement.element( "PHOTO").element( "BINVAL");
if (element.getTextTrim() == null || element.getTextTrim().isEmpty()) {
Log.trace("No vCard binval content for '{}'", username);
response.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
final String contentType = vCardElement.element( "PHOTO" ).element( "TYPE" ).getTextTrim();
if (contentType == null || contentType.isEmpty()) {
Log.trace("No vCard type content for '{}'", username);
response.setStatus(HttpStatus.SC_NO_CONTENT);
return;
}
// Read data from VCard.
final String value = element.getTextTrim().replaceAll("\\s","");
final byte[] decoded = Base64.getDecoder().decode(value);
// Output data.
if (decoded != null) {
writeBytesToStream(contentType, decoded, response);
}
}
/**
* Writes out a byte to the ServletOuputStream.
*
* @param bytes the bytes to write to the ServletOutputStream.
*/
private void writeBytesToStream(String contentType, byte[] bytes, HttpServletResponse response) {
response.setContentType(contentType);
// Send image
try (ServletOutputStream sos = response.getOutputStream()) {
sos.write(bytes);
sos.flush();
}
catch (IOException e) {
// Do nothing
}
}
}