-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathReceiveBuildServlet.java
More file actions
87 lines (76 loc) · 3.5 KB
/
Copy pathReceiveBuildServlet.java
File metadata and controls
87 lines (76 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the MIT License https://raw.github.com/mit-cml/app-inventor/master/mitlicense.txt
package com.google.appinventor.server;
import com.google.appinventor.server.encryption.EncryptionException;
import com.google.appinventor.server.project.utils.Security;
import com.google.appinventor.server.storage.StorageIo;
import com.google.appinventor.server.storage.StorageIoInstanceHolder;
import com.google.appinventor.shared.storage.StorageUtil;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet for receiving build output files and build error information from a Build Server.
*
* <p>This needs to be done from a servlet that does not require login because
* posts from the Build Server do not contain login information. To ensure
* safety they contain an encrypted user and project ID as part of
* their URL.
*
* @author markf@google.com (Mark Friedman)
*/
public class ReceiveBuildServlet extends OdeServlet {
// Logging support
private static final Logger LOG = Logger.getLogger(ReceiveBuildServlet.class.getName());
private final OdeAuthFilter odeFilter = new OdeAuthFilter();
private final transient StorageIo storageIo = StorageIoInstanceHolder.INSTANCE;
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// URIs for receivebuild requests are structured as follows:
// /<baseurl>/receivebuild/encryptedUserAndProjectId/fileId
String uriComponents[] = req.getRequestURI().split("/", 5);
// TODO(lizlooney,user) If the URI doesn't contain enough components, the following lines
// will throw an ArrayIndexOutOfBoundsException. We could deal with that outcome more cleanly
// by returning an HTTP error code. This applies to all of our servlets.
String userId;
long projectId;
try {
userId = Security.decryptUserId(uriComponents[3]);
projectId = Security.decryptProjectId(uriComponents[3]);
} catch (EncryptionException e) {
throw CrashReport.createAndLogError(LOG, req, null, e);
}
// Set the user in the OdeFilter, which is used everywhere as the UserInfoProvider.
odeFilter.setUserFromUserId(userId);
try {
String buildFileDirPath = uriComponents[4];
ZipInputStream zipInputStream = new ZipInputStream(req.getInputStream());
while (true) {
ZipEntry zipEntry = zipInputStream.getNextEntry();
if (zipEntry == null) {
break;
}
String fileName = zipEntry.getName();
byte[] fileBytes = ByteStreams.toByteArray(zipInputStream);
if (StorageUtil.ANDROID_KEYSTORE_FILENAME.equals(fileName)) {
LOG.info("Saving android.keystore for user: " + userId);
storageIo.addFilesToUser(userId, StorageUtil.ANDROID_KEYSTORE_FILENAME);
storageIo.uploadRawUserFile(userId, fileName, fileBytes);
} else {
String filePath = buildFileDirPath + "/" + fileName;
LOG.info("Saving build output files: " + filePath);
storageIo.addOutputFilesToProject(userId, projectId, filePath);
storageIo.uploadRawFile(projectId, filePath, userId, fileBytes);
}
}
} finally {
odeFilter.removeUser();
}
}
}