Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
*/
package org.asynchttpclient.request.body.multipart;

import jakarta.activation.MimetypesFileTypeMap;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import static org.asynchttpclient.util.MiscUtils.withDefault;
Expand All @@ -28,16 +24,6 @@
*/
public abstract class FileLikePart extends PartBase {

private static final MimetypesFileTypeMap MIME_TYPES_FILE_TYPE_MAP;

static {
try (InputStream is = FileLikePart.class.getResourceAsStream("ahc-mime.types")) {
MIME_TYPES_FILE_TYPE_MAP = new MimetypesFileTypeMap(is);
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
}

/**
* Default content encoding of file attachments.
*/
Expand All @@ -63,7 +49,7 @@ protected FileLikePart(String name, String contentType, Charset charset, String
}

private static String computeContentType(String contentType, String fileName) {
return contentType != null ? contentType : MIME_TYPES_FILE_TYPE_MAP.getContentType(withDefault(fileName, ""));
return contentType != null ? contentType : MimeTypes.getContentType(withDefault(fileName, ""));
}

public String getFileName() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2026 AsyncHttpClient Project. 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.asynchttpclient.request.body.multipart;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
* Maps file extensions to content types using the bundled {@code ahc-mime.types} resource.
*
* <p>This is a self-contained replacement for {@code jakarta.activation.MimetypesFileTypeMap}, which was
* previously used solely to resolve the content type of {@link FileLikePart}s. The lookup mirrors the
* {@code MimetypesFileTypeMap} contract: the extension is the substring after the last {@code '.'}, and an
* unknown or missing extension resolves to {@value #DEFAULT_CONTENT_TYPE}. Unlike the original, the lookup is
* case-insensitive and relies exclusively on the bundled resource, so detection is deterministic across
* machines and classpaths.
*/
final class MimeTypes {

static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";

/**
* Lower-cased file extension to content type. Built once at class load from {@code ahc-mime.types}.
*/
private static final Map<String, String> EXTENSION_TO_CONTENT_TYPE;

static {
Map<String, String> map = new HashMap<>();
// The MimetypesFileTypeMap format: '#' comments, blank lines, and whitespace-delimited
// "type ext1 ext2 ..." entries. A later mapping for the same extension wins, matching the
// original Hashtable-based implementation.
try (InputStream is = MimeTypes.class.getResourceAsStream("ahc-mime.types");
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.ISO_8859_1))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.isEmpty() || line.charAt(0) == '#') {
continue;
}
String[] tokens = line.split("\\s+");
for (int i = 1; i < tokens.length; i++) {
map.put(tokens[i].toLowerCase(Locale.ROOT), tokens[0]);
}
}
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
EXTENSION_TO_CONTENT_TYPE = Collections.unmodifiableMap(map);
}

private MimeTypes() {
// Prevent outside initialization
}

/**
* Resolves the content type for the given file name based on its extension.
*
* @param fileName the file name (may include a path; only the part after the last {@code '.'} is used)
* @return the mapped content type, or {@value #DEFAULT_CONTENT_TYPE} if the extension is absent or unknown
*/
static String getContentType(String fileName) {
int dot = fileName.lastIndexOf('.');
if (dot < 0) {
return DEFAULT_CONTENT_TYPE;
}
String extension = fileName.substring(dot + 1);
if (extension.isEmpty()) {
return DEFAULT_CONTENT_TYPE;
}
return EXTENSION_TO_CONTENT_TYPE.getOrDefault(extension.toLowerCase(Locale.ROOT), DEFAULT_CONTENT_TYPE);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file maps Internet media types to unique file extension(s).
# Although created for httpd, this file is used by many software systems
# and has been placed in the public domain for unlimited redisribution.
# and has been placed in the public domain for unlimited redistribution.
#
# The table below contains both registered and (common) unregistered types.
# A type that has no unique extension can be ignored -- they are listed
Expand Down Expand Up @@ -94,6 +94,7 @@ application/ecmascript ecma
# application/edi-consent
# application/edi-x12
# application/edifact
# application/efi
# application/emergencycalldata.comment+xml
# application/emergencycalldata.deviceinfo+xml
# application/emergencycalldata.providerinfo+xml
Expand All @@ -111,10 +112,9 @@ application/exi exi
# application/fastsoap
# application/fdt+xml
# application/fits
# application/font-sfnt
application/font-tdpfr pfr
application/font-woff woff
# application/framework-attributes+xml
# application/geo+json
application/gml+xml gml
application/gpx+xml gpx
application/gxf gxf
Expand Down Expand Up @@ -142,7 +142,7 @@ application/ipfix ipfix
application/java-archive jar
application/java-serialized-object ser
application/java-vm class
application/javascript js
# application/javascript
# application/jose
# application/jose+json
# application/jrd+json
Expand All @@ -156,6 +156,7 @@ application/jsonml+json jsonml
# application/kpml-request+xml
# application/kpml-response+xml
# application/ld+json
# application/lgr+xml
# application/link-format
# application/load-control+xml
application/lost+xml lostxml
Expand Down Expand Up @@ -358,13 +359,15 @@ application/vnd.3gpp.pic-bw-large plb
application/vnd.3gpp.pic-bw-small psb
application/vnd.3gpp.pic-bw-var pvb
# application/vnd.3gpp.sms
# application/vnd.3gpp.sms+xml
# application/vnd.3gpp.srvcc-ext+xml
# application/vnd.3gpp.srvcc-info+xml
# application/vnd.3gpp.state-and-event-info+xml
# application/vnd.3gpp.ussd+xml
# application/vnd.3gpp2.bcmcsinfo+xml
# application/vnd.3gpp2.sms
application/vnd.3gpp2.tcap tcap
# application/vnd.3lightssoftware.imagescal
application/vnd.3m.post-it-notes pwn
application/vnd.accpac.simply.aso aso
application/vnd.accpac.simply.imp imp
Expand All @@ -383,6 +386,7 @@ application/vnd.ahead.space ahead
application/vnd.airzip.filesecure.azf azf
application/vnd.airzip.filesecure.azs azs
application/vnd.amazon.ebook azw
# application/vnd.amazon.mobi8-ebook
application/vnd.americandynamics.acc acc
application/vnd.amiga.ami ami
# application/vnd.amundsen.maze+xml
Expand Down Expand Up @@ -419,6 +423,7 @@ application/vnd.businessobjects rep
# application/vnd.cendio.thinlinc.clientconf
# application/vnd.century-systems.tcp_stream
application/vnd.chemdraw+xml cdxml
# application/vnd.chess-pgn
application/vnd.chipnuts.karaoke-mmd mmd
application/vnd.cinderella cdy
# application/vnd.cirpack.isdn-ext
Expand All @@ -432,9 +437,11 @@ application/vnd.cluetrust.cartomobile-config-pkg c11amz
# application/vnd.collection+json
# application/vnd.collection.doc+json
# application/vnd.collection.next+json
# application/vnd.comicbook+zip
# application/vnd.commerce-battelle
application/vnd.commonspace csp
application/vnd.contact.cmsg cdbcmsg
# application/vnd.coreos.ignition+json
application/vnd.cosmocaller cmc
application/vnd.crick.clicker clkx
application/vnd.crick.clicker.keyboard clkk
Expand Down Expand Up @@ -578,6 +585,7 @@ application/vnd.genomatix.tuxedo txd
# application/vnd.geo+json
# application/vnd.geocube+xml
application/vnd.geogebra.file ggb
application/vnd.geogebra.slides ggs
application/vnd.geogebra.tool ggt
application/vnd.geometry-explorer gex gre
application/vnd.geonext gxt
Expand Down Expand Up @@ -886,6 +894,8 @@ application/vnd.olpc-sugar xo
application/vnd.oma.dd2+xml dd2
# application/vnd.oma.drm.risd+xml
# application/vnd.oma.group-usage-list+xml
# application/vnd.oma.lwm2m+json
# application/vnd.oma.lwm2m+tlv
# application/vnd.oma.pal+xml
# application/vnd.oma.poc.detailed-progress-report+xml
# application/vnd.oma.poc.final-report+xml
Expand All @@ -899,6 +909,7 @@ application/vnd.oma.dd2+xml dd2
# application/vnd.omads-file+xml
# application/vnd.omads-folder+xml
# application/vnd.omaloc-supl-init
# application/vnd.onepager
# application/vnd.openblox.game+xml
# application/vnd.openblox.game-binary
# application/vnd.openeye.oeb
Expand Down Expand Up @@ -1013,6 +1024,7 @@ application/vnd.pvi.ptid1 ptid
# application/vnd.pwg-multiplexed
# application/vnd.pwg-xhtml-print+xml
# application/vnd.qualcomm.brew-app-res
# application/vnd.quarantainenet
application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
# application/vnd.quobject-quoxdocument
# application/vnd.radisys.moml+xml
Expand All @@ -1032,6 +1044,7 @@ application/vnd.quark.quarkxpress qxd qxt qwd qwt qxl qxb
# application/vnd.radisys.msml-dialog-transform+xml
# application/vnd.rainstor.data
# application/vnd.rapid
# application/vnd.rar
application/vnd.realvnc.bed bed
application/vnd.recordare.musicxml mxl
application/vnd.recordare.musicxml+xml musicxml
Expand Down Expand Up @@ -1077,6 +1090,7 @@ application/vnd.smart.teacher teacher
application/vnd.solent.sdkm+xml sdkm sdkd
application/vnd.spotfire.dxp dxp
application/vnd.spotfire.sfs sfs
application/vnd.sqlite3 sqlite sqlite3
# application/vnd.sss-cod
# application/vnd.sss-dtf
# application/vnd.sss-ntf
Expand Down Expand Up @@ -1146,6 +1160,7 @@ application/vnd.uoml+xml uoml
application/vnd.vcx vcx
# application/vnd.vd-study
# application/vnd.vectorworks
# application/vnd.vel+json
# application/vnd.verimatrix.vcas
# application/vnd.vidsoft.vidconference
application/vnd.visio vsd vst vss vsw
Expand Down Expand Up @@ -1199,6 +1214,7 @@ application/vnd.zul zir zirz
application/vnd.zzazz.deck+xml zaz
application/voicexml+xml vxml
# application/vq-rtcpxr
application/wasm wasm
# application/watcherinfo+xml
# application/whoispp-query
# application/whoispp-response
Expand Down Expand Up @@ -1246,12 +1262,10 @@ application/x-font-bdf bdf
application/x-font-ghostscript gsf
# application/x-font-libgrx
application/x-font-linux-psf psf
application/x-font-otf otf
application/x-font-pcf pcf
application/x-font-snf snf
# application/x-font-speedo
# application/x-font-sunos-news
application/x-font-ttf ttf ttc
application/x-font-type1 pfa pfb pfm afm
# application/x-font-vfont
application/x-freearc arc
Expand Down Expand Up @@ -1428,7 +1442,7 @@ audio/mp4 m4a mp4a
audio/mpeg mpga mp2 mp2a mp3 m2a m3a
# audio/mpeg4-generic
# audio/musepack
audio/ogg oga ogg spx
audio/ogg oga ogg spx opus
# audio/opus
# audio/parityfec
# audio/pcma
Expand Down Expand Up @@ -1519,17 +1533,32 @@ chemical/x-cml cml
chemical/x-csml csml
# chemical/x-pdb
chemical/x-xyz xyz
font/collection ttc
font/otf otf
# font/sfnt
font/ttf ttf
font/woff woff
font/woff2 woff2
image/avif avif
image/bmp bmp
image/cgm cgm
# image/dicom-rle
# image/emf
# image/example
# image/fits
image/g3fax g3
image/gif gif
image/heic heic
image/heic-sequence heics
image/heif heif
image/heif-sequence heifs
image/ief ief
# image/jls
# image/jp2
image/jpeg jpeg jpg jpe
# image/jpm
# image/jpx
image/jxl jxl
image/ktx ktx
# image/naplps
image/png png
Expand Down Expand Up @@ -1572,6 +1601,7 @@ image/vnd.wap.wbmp wbmp
image/vnd.xiff xif
# image/vnd.zbrush.pcx
image/webp webp
# image/wmf
image/x-3ds 3ds
image/x-cmu-raster ras
image/x-cmx cmx
Expand Down Expand Up @@ -1611,6 +1641,7 @@ message/rfc822 eml mime
# message/vnd.si.simp
# message/vnd.wfa.wsc
# model/example
# model/gltf+json
model/iges igs iges
model/mesh msh mesh silo
model/vnd.collada+xml dae
Expand All @@ -1621,7 +1652,7 @@ model/vnd.gdl gdl
# model/vnd.gs.gdl
model/vnd.gtw gtw
# model/vnd.moml+xml
model/vnd.mts mts
# model/vnd.mts
# model/vnd.opengex
# model/vnd.parasolid.transmit.binary
# model/vnd.parasolid.transmit.text
Expand Down Expand Up @@ -1664,7 +1695,7 @@ text/csv csv
# text/fwdred
# text/grammar-ref-list
text/html html htm
# text/javascript
text/javascript js mjs
# text/jcr-cnd
# text/markdown
# text/mizar
Expand All @@ -1675,6 +1706,7 @@ text/plain txt text conf def list log in
# text/provenance-notation
# text/prs.fallenstein.rst
text/prs.lines.tag dsc
# text/prs.prop.logic
# text/raptorfec
# text/red
# text/rfc822-headers
Expand Down Expand Up @@ -1759,7 +1791,7 @@ video/jpm jpm jpgm
video/mj2 mj2 mjp2
# video/mp1s
# video/mp2p
# video/mp2t
video/mp2t ts m2t m2ts mts
video/mp4 mp4 mp4v mpg4
# video/mp4v-es
video/mpeg mpeg mpg mpe m1v m2v
Expand Down
Loading
Loading