File upload for Netty 4.x example - file-upload

How make upload http file server with Netty 4.x ? For 3.x is an example, for 4.x example only for serving static file.

I use netty-all:4.1.32.Final do upload file server
// Post request
private void formParams(HttpServerRequest request, ByteBuf content, Map<String, String> formParams, Map<String, MemoryFileUpload> fileParams) {
if (content != null) {
// POST Params
FullHttpRequest dhr = new DefaultFullHttpRequest(request.version(), request.method(), request.uri(), content, request.requestHeaders(), EmptyHttpHeaders.INSTANCE);
HttpPostRequestDecoder postDecoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), dhr);
List<InterfaceHttpData> postData = postDecoder.getBodyHttpDatas();
for (InterfaceHttpData data : postData) {
// General Post Content
if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
MemoryAttribute attribute = (MemoryAttribute) data;
formParams.put(attribute.getName(), attribute.getValue());
}
// Upload
else if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
MemoryFileUpload fileUpload = (MemoryFileUpload) data;
fileParams.put(fileUpload.getName(), fileUpload);
}
}
}
}

HttpPostRequestDecoder is not ported to 4.0.0.x yet. So there is no support for it atm. It's on the to-do-list.

Related

HttpRequest DELETE with body

I have to submit an http DELETE request containing a body. I know how I can do it, but in my case it uses java.net.http.HttpRequest. Unfortunately, this component only allows submission of BodyPublisher to PUT and POST requests.
My question is, is there any way to use HttpRequest for the problematic DELETE request?
You can use the HttpRequest.Builder::method that takes two arguments:
HttpClient client = HttpClient.newBuilder().proxy(HttpClient.Builder.NO_PROXY).build();
HttpServer server = HttpServer.create();
server.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0);
server.createContext("/test/", new HttpHandler() {
#Override
public void handle(HttpExchange exchange) throws IOException {
byte[] bytes = exchange.getRequestBody().readAllBytes();
exchange.sendResponseHeaders(200, bytes.length == 0 ? -1 : bytes.length);
try (OutputStream os = exchange.getResponseBody()) {
os.write(bytes);
}
}
});
server.start();
try {
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI("http", null,
server.getAddress().getHostString(),
server.getAddress().getPort(),
"/test/test", null, null))
.method("DELETE", HttpRequest.BodyPublishers.ofString("hahaha...")).build();
var resp = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(resp);
System.out.println(resp.body());
} finally {
server.stop(0);
}

XmlHttpRequest and AEM Servlet

I am making an raw ajax call on the clientside, which look like the following,
var url = '/bin/denisa/dummyServlet';
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xhr.setRequestHeader('Accept', 'application/json, text/javascript, */*; q=0.01');
xhr.onload = function() {
if (xhr.status === 200) {
alert('deni');
}
else {
alert('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send();
to the following servlet in AEM:
#Component(
service = {
Servlet.class
},
property = {
"sling.servlet.paths=/bin/denisa/dummyServlet",
"sling.servlet.extensions=json",
"sling.servlet.methods=GET"
}
)
public class DummyServlet extends SlingSafeMethodsServlet {
private static final Logger LOG = LoggerFactory.getLogger(DummyServlet .class);
#Reference
private dummyService dummyService;
#Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(dummyService);
response.setContentType("application/json");
response.getWriter().write(gson.toJson(jsonElement));
}
}
And I got a 404, and i don't know exactly why because the path is the same, and also contentTypes. Does anybody has a clue?
Your code looks good it seems something is missing on the config side
can you log in to the felix console
http://localhost:4502/system/console/bundles
Expand you project bundle and check for your servlet
with Service ID xx Types: javax.servlet.Servlet and other details
*Also ensure the bundle is not installed and in active state
Then go to http://localhost:4502/system/console/configMgr and verify Apache Sling Servlet/Script Resolver execution paths contain /bin/ entry
If above mentioned configs are navigate to http://localhost:4502/system/console/servletresolver
check for servlet response.
These are some of the configuration which helped me to resolve 404

Apache HttpClient - Default protocol

I am using Apache HttpClient to send a POST requests. How can I determine which PROTOCOL my Apache HttpClient instance is using for sending "https://" requests. I use following code block to send my POST requests.
public void sendPostURL(String url, HashMap<String, String>params, String user, String pass) {
HttpClient client = new HttpClient();
String urlContent = "";
PostMethod method = new PostMethod("https://...");
// Prepare connection information
client.getParams().setParameter("http.useragent", "MyApp");
if ( (user != null) &&(pass != null) ) {
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(AuthScope.ANY, (new UsernamePasswordCredentials(user, pass)));
}
// Prepare parameters
for (Map.Entry<String, String> entry : params.entrySet()) {
method.addParameter(entry.getKey(), ((entry.getValue() != null) ? entry.getValue().toString() : ""));
}
try{
// HTTP execution
int returnCode = client.executeMethod(method);
} catch (Exception e) {
// Exception
e.printStackTrace();
} finally {
method.releaseConnection();
}
}
Please guide me on how can I get the PROTOCOL that HttpClient is using to send the request. Also how can I override the PROTOCOL used. Hoping for a solution. Thanks in advance.
The protocol is HTTPS, is it not ?

Image HttpMessageResponse responding but not displaying?

I'm currently updating an old site to use the Hot Towel framework and one of the the things the current site does is load an image using the HTTPMessageResponse. This works fine in the the old set up however on the new set up the image is not displayed and going to the URL produces...
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.ByteArrayContent, Headers: { Content-Type: image/png }
I've had a look at the response both apps produce, and the responses from the following function match (the response is the same as above and the contents are a perfect match)...
namespace OPC.Controllers
{
public class ImageController : Controller
{
public HttpResponseMessage GetImage(int imageId)
{
var blob = new byte[10];
var context = new OPCEntity();
var ImageString = context.sp_GetImageData(imageId);
foreach (var Result in ImageString)
{
blob = Result.Data;
}
Image image;
var ms = new MemoryStream();
ms.Write(blob, 0, blob.Length);
var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(ms.ToArray());
result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
return result;
}
}
}
The image is set in the JS using...
image.setAttribute('src', document.location.href.match(/(^[^#]*)/)[0] + '/Image/GetImage?imageId=' + imageDetails.imageId);
Does anyone have any ideas on what I could be missing, or if anything in the Hot Towel framework could be interfering.
Many Thanks in advance.
Well I have missed something important... the fact that it should be...
public class ImageController : ApiController{}
However I have also found that the breeze web API config does conflict with the normal web API config so for the time being I've had to change BreezeWebApiConfig.cs to the following
public static class BreezeWebApiConfig {
public static void RegisterBreezePreStart() {
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "BreezeApi",
routeTemplate: "api/{controller}/{action}"
);
}
}

JavaFX: File upload to REST service / servlet fails because of missing boundary

I'm trying to upload a file using JavaFX using the HttpRequest. For this purpose I have written the following function.
function uploadFile(inputFile : File) : Void {
// check file
if (inputFile == null or not(inputFile.exists()) or inputFile.isDirectory()) {
return;
}
def httpRequest : HttpRequest = HttpRequest {
location: urlConverter.encodeURL("{serverUrl}");
source: new FileInputStream(inputFile)
method: HttpRequest.POST
headers: [
HttpHeader {
name: HttpHeader.CONTENT_TYPE
value: "multipart/form-data"
}
]
}
httpRequest.start();
}
On the server side, I am trying to handle the incoming data using the Apache Commons FileUpload API using a Jersey REST service. The code used to do this is a simple copy of the FileUpload tutorial on the Apache homepage.
#Path("Upload")
public class UploadService {
public static final String RC_OK = "OK";
public static final String RC_ERROR = "ERROR";
#POST
#Produces("text/plain")
public String handleFileUpload(#Context HttpServletRequest request) {
if (!ServletFileUpload.isMultipartContent(request)) {
return RC_ERROR;
}
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List<FileItem> items = null;
try {
items = upload.parseRequest(request);
}
catch (FileUploadException e) {
e.printStackTrace();
return RC_ERROR;
}
...
}
}
However, I get a exception at items = upload.parseRequest(request);:
org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
I guess I have to add a manual boundary info to the InputStream. Is there any easy solution to do this? Or are there even other solutions?
Have you tried just using the InputStream from HttpServletRequest like so
InputStream is = httpRequest.getInputStream();
BufferedInputStream in = new BufferedInputStream(is);
//Write out bytes
out.close();
is.close();