Serving images with Akka-http - static

I'm trying to serve an image using akka-http, but keep getting error in the browser about MIME type:
Resource interpreted as Document but transferred with MIME type image/png: "http://localhost/banners/ci.png".
That's the server-side code:
pathPrefix("banners"){
get {
entity(as[HttpRequest]) { requestData =>
complete {
val fullPath = requestData.uri.path.toString match {
case _ => Paths.get(workingDirectory + requestData.uri.path.toString)
}
val contentType = getExtensions(fullPath.toString) match {
case "jpg" => ContentType(MediaTypes.`image/jpeg`)
case "png" => ContentType(MediaTypes.`image/png`)
case "html" => ContentTypes.`text/html(UTF-8)`
}
val h = RawHeader("Access-Control-Allow-Origin","*")
val byteArray = Files.readAllBytes(fullPath)
HttpResponse(OK, entity = HttpEntity(contentType,byteArray)).withHeaders(h)
}
}
}
} ~
Here is the response headers copied from chrome developer console:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Server: akka-http/10.0.7
Date: Fri, 26 May 2017 13:08:04 GMT
Content-Type: image/png
Content-Length: 581
Any ideas how can I fix it ?

Related

wkhtmltopdf reported an error: Exit with code 1 due to network error: ContentNotFoundError

good day, please im having this error when i click Export to pdf button…………………
‘’’
views.py
#login_required(login_url='loginpage')
#cache_control(no_cache=True, must_rev alidate=True, no_store=True)
def exportToPdf(request, pk):
c = get_object_or_404(candidate, id=pk)
cookies = request.COOKIES
options = {
'page-size': 'Letter',
'encoding': "UTF-8",
'cookie' : [
('csrftoken', cookies ['csrftoken']),
('sessionid', cookies ['sessionid'])
]
}
pdf = pdfkit.from_url('http://127.0.0.1:8000/'+str(c.id), False, options = options)
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-disposition'] = 'attachment; filename=candidate.pdf'
return response
urls.py
path('int:pk/exporttopdf/', views.exportToPdf, name='exporttopdf'),
‘’’

Self-hosted Nancy instance returning 404 errors

I'm trying to get a self-hosted Nancy app running, but I'm having trouble getting it to return valid responses. I'm new at Nancy; I expect my problem is something fairly simple.
Here's some code:
class Program
{
static void Main(string[] args)
{
const String PORT_SETTING = "webServicePortNumber";
const String URI = "http://localhost:{0}/download/";
var portNum = ConfigurationManager.AppSettings[PORT_SETTING];
var uri = new Uri(String.Format(URI, portNum));
var config = new HostConfiguration {
UrlReservations = new UrlReservations { CreateAutomatically = true }
};
using (var nancyHost = new NancyHost(new Bootstrapper(), config, uri)) {
nancyHost.Start();
Console.WriteLine(String.Format("Listening on {0}. Press any key to stop.", uri.AbsoluteUri));
Console.ReadKey();
}
Console.WriteLine("Stopped. Press any key to exit.");
Console.ReadKey();
}
}
internal class Bootstrapper : DefaultNancyBootstrapper
{
protected override Nancy.Diagnostics.DiagnosticsConfiguration DiagnosticsConfiguration
{
get {
return new DiagnosticsConfiguration {
Password = #"[password]"
};
}
}
}
My NancyModule looks like this:
public class DownloadsModule : NancyModule
{
public DownloadsModule() : base("/download")
{
RegisterRoutes();
}
private void RegisterRoutes()
{
Put["/"] = parms => InitiateDownload(parms);
Get["/"] = parms => Summary(parms);
Get["/{id}"] = parms => GetStatus(parms.requestId);
}
private Response GetStatus(Guid requestId)
{
return Response.AsText("TEST: GetStatus requestId " + requestId);
}
private Response Summary(dynamic parms)
{
return Response.AsText("Summary: You loved me before, do you love me now?");
}
private Response InitiateDownload(dynamic parms)
{
return Response.AsText("InitiateDownload.");
}
}
Nancy is running; I can access the diagnostics at http://127.0.0.1:8880/download/_Nancy/. Looking at them, the routes appear ready. Interactive Diagnostics/GetAllRoutes shows:
P U T
name: [nothing] path: /download
G E T
name: [nothing] path: /download
name: [nothing] path: /download/{id}
And yet, I'm getting 404s back when I try http://localhost:8880/download/.
The request trace on the diagnostics page shows:
Method: GET
Request Url:
Scheme: http
Host Name: localhost
Port: 8880
Base Path: /download
Path: /
Query:
Site Base: http://localhost:8880
Is Secure: false
Request Content Type:
Response Content Type: text/html
Request Headers:
<snip>
Accept: text/html;q=1
application/xhtml+xml;q=1
image/webp;q=1
application/xml;q=0.9
*/*;q=0.8
<snip>
Response Headers:
Status Code: 404
Log: New Request Started
[DefaultResponseNegotiator] Processing as real response
So why isn't Nancy routing this request to the proper route?
Problem pointed out to me by jchannon in the Nancy JabbR room:
The URI specifies http://localhost:{0}/download/, while the module also specifies a base path of /download, so currently its looking for an URL of http://localhost:{0}/download/download/

How can I send a file from the server to client using REST (JAX-RS Jersey)?

I want to send a file from my server side (EJB) using REST Jersey (JAX-RS).
I am trying with the following code,
Public Response getFiles() {
File file = new File(fileName);
FileOutputStream dest = new FileOutputStream(file);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
out.putNextEntry(new ZipEntry(fileName));
final ResponseBuilder response = Response.ok(out);
response.header("Content-Type", "*/*");
response.header("Content-Disposition", "attachment; filename=" + file.getName() + ".zip");
return response.build();
}
But I am getting the exception message
type class java.util.zip.ZipOutputStream, and MIME media type */* was not found
SEVERE: The registered message body writers compatible with the MIME media type are:
Also tried with "Content-Type" , "application/octet-stream", "application/x-www-form-urlencoded" and multipart/form-data
But none of them is working.
Use application/zip.
#GET
#Produces("application/zip")
public Response getZip() {
final File f = new File("/tmp/foo.zip");
ResponseBuilder response = Response.ok((Object) f);
response.header("Content-Disposition", "attachment; filename=" + f.getName());
return response.build();
}
application/octet-stream + gzip
#GET
#Path("/getFiles")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFiles() {
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream output) throws IOException, WebApplicationException {
String filePath = "/yourFile.pdf";
java.nio.file.Path path = Paths.get(filePath);
byte[] data = Files.readAllBytes(path);
output.write(data);
output.flush();
}
};
return Response.ok(stream).build();
}
and a jersey filter added to web.xml
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.GZIPContentEncodingFilter</param-value>
</init-param>
when making the request:
send a header of "Accept" with value of "application/octet-stream"
and a header of "Accept-Encoding" with value of "gzip"

get 404 error by batch file upload via google-api-javascript-client library

I'm trying to upload whole folder to google drive.
I could successfully upload one file by one request.
But I met rateLimitExceed error while upload whole files.
So, I tried to use batch request.
Creating folders with batch request are successfully done.
but when I trying to upload file by batch request, it returns 404 error. ( Not Found )
Is this google drive's bug?
If so, should I do time delay for upload many files?
var boundary = '--314159265358979323846';
var delimiter = "\r\n--" + boundary + "\r\n";
var close_delim = "\r\n--" + boundary + "--";
var contentType = 'text/plain';
var metadata = {
'title': 'test1.txt',
'mimeType': contentType
};
var base64Data = btoa('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
var multipartRequestBody =
delimiter +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(metadata) +
delimiter +
'Content-Type: ' + contentType + '\r\n' +
'Content-Transfer-Encoding: base64\r\n' +
'\r\n' +
base64Data +
close_delim;
var request = gapi.client.request({
'path': '/upload/drive/v2/files',
'method': 'POST',
'params': {'uploadType': 'multipart'},
'headers': {
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
},
'body': multipartRequestBody});
var httpBatch = gapi.client.newHttpBatch();
httpBatch.add(request, {
callback: function(resp, rawResp){
console.log(rawResp);
}
});
httpBatch.execute(function(resp, rawResp){
console.log(rawResp)
});
error is here:
{"id":"1171148984","result":false}
{"gapiRequest":{"data":{"body":"--batch_YZmy6yr9vIk=_ABqi-xumfFQ=\r\nContent-Type: application/http\r\nContent-ID: <response-1171148984>\r\n\r\nHTTP/1.1 404 Not Found\r\nContent-Type: text/html; charset=UTF-8\r\nDate: Mon, 21 Oct 2013 07:53:20 GMT\r\nExpires: Mon, 21 Oct 2013 07:53:20 GMT\r\nCache-Control: private, max-age=0\r\nContent-Length: 9\r\n\r\nNot Found\r\n--batch_YZmy6yr9vIk=_ABqi-xumfFQ=--\r\n","headers":{"pragma":"no-cache","date":"Mon, 21 Oct 2013 07:53:20 GMT","server":"GSE","content-type":"multipart/mixed; boundary=batch_YZmy6yr9vIk=_ABqi-xumfFQ=","cache-control":"no-cache, no-store, max-age=0, must-revalidate","content-length":"349","expires":"Fri, 01 Jan 1990 00:00:00 GMT"},"status":200,"statusText":"OK"}}}
Uploading cannot be batched, please run the upload requests individually.

Set ACL for Google Storage Object with JSON Api in Appengine

I would like to ADD a ACL to a Google Storage object using the Json API from appengine. I have tried the following code, however I get a 400 response with no details. I am not using the java-client-libraries, however I am willing to try. Below is my code:
public static void updateACL(String bucket, String object,
List<String> emails) {
try {
ArrayList scopes = new ArrayList();
scopes.add("https://www.googleapis.com/auth/devstorage.full_control");
AppIdentityService appIdentity = AppIdentityServiceFactory
.getAppIdentityService();
AppIdentityService.GetAccessTokenResult accessToken = appIdentity
.getAccessToken(scopes);
// The token asserts the identity reported by
// appIdentity.getServiceAccountName()
logger.log(Level.WARNING, "bucket: "+bucket+" object: "+object+ " email: "+emails.get(0));
JSONObject request = new JSONObject();
request.put("entity", "user-" + emails.get(0));
request.put("roles", "READER");
URL url = new URL("https://www.googleapis.com/storage/v1beta1/b/"
+ bucket + "/o/"+object+"/acl?key=" + API_KEY);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Authorization", "OAuth "
+ accessToken.getAccessToken());
String urlParameters = "bucket=" + bucket + "&object=" + object;
OutputStreamWriter writer = new OutputStreamWriter(
connection.getOutputStream());
request.write(writer);
writer.close();
logger.log(Level.WARNING, connection.getResponseMessage());
logger.log(Level.WARNING,
String.valueOf(connection.getResponseCode()));
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
// Note: Should check the content-encoding.
// JSONTokener response_tokens = new
// JSONTokener(connection.getInputStream());
// JSONObject response = new JSONObject(response_tokens);
// return (String) response.get("id");
return;
} else {
Scanner s;
s = new Scanner(connection.getErrorStream());
s.useDelimiter("\\Z");
String response = s.next();
s.close();
throw new Exception(connection.getResponseCode()+" "+connection.getResponseMessage()+
response);
}
} catch (Exception e) {
logger.log(Level.WARNING, "exception: "+e.getMessage());
}
}
The response I get is a 400, but the details are not helpful at all.
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Required"
}
],
"code": 400,
"message": "Required"
}
}
I suspect there's a tiny bug or two in your code. In this particular instance it looks like you are sending roles when the JSON api expects role.
One thing I find helpful for debugging is to compare what my code is sending over the wire with the HTTP request the Google APIs explorer generates.
Navigate to https://developers.google.com/storage/docs/json_api/v1/objectAccessControls/insert
Turn on the Authorize requests using OAuth 2.0 button.
Set the bucket, object, entity and role fields.
Click execute.
You should see the resulting HTTP request and response.
Request:
POST https://www.googleapis.com/storage/v1beta1/b/bucket/o/obj/acl?key={YOUR_API_KEY}
Content-Type: application/json
Authorization: Bearer ya29.1111111111111111111111111111111111-aaaaaaaaaaaaa
X-JavaScript-User-Agent: Google APIs Explorer
{
"entity": "user-person#example.com",
"role": "READER"
}
Response:
200 OK
- Hide headers -
cache-control: no-cache, no-store, max-age=0, must-revalidate
content-type: application/json; charset=UTF-8
date: Fri, 30 Nov 2012 02:16:57 GMT
etag: "fP_WVz7o95h5w16zKezUFJzMmHg/6CyL8wOk_60IJhaxNewPk1fHpQo"
expires: Fri, 01 Jan 1990 00:00:00 GMT
server: GSE
{
"kind": "storage#objectAccessControl",
"id": "bucket/obj/user-person#example.com",
"selfLink": "https://www.googleapis.com/storage/v1beta1/b/bucket/o/obj/acl/user-person#example.com",
"bucket": "bucket",
"object": "obj",
"entity": "user-person#example.com",
"role": "READER",
"email": "person#example.com"
}
Now make sure the request you are sending over the wire looks the same as this one.

Resources