Вот мой ссылочный код:
Код: Выделить всё
class NanoHttpServer(private val activity: AndroidIosFileShareActivity, port: Int) : NanoHTTPD(port) {
override fun serve(session: IHTTPSession): Response {
val uri = session.uri
Log.d(TAG, "Session uri: $uri")
return try {
when {
session.method == Method.GET && session.uri == "/exchange-ip" -> {
handleIpExchange(session)
}
session.method == Method.POST && session.uri == "/upload" -> {
postUpload2(session)
}
else -> {
newFixedLengthResponse(Response.Status.METHOD_NOT_ALLOWED, MIME_PLAINTEXT, "Only POST and GET methods are allowed")
}
}
} catch (e: Exception) {
e.printStackTrace()
newFixedLengthResponse(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "Error during upload: ${e.message}")
}
}
// Handle IP exchange for the GET /exchange-ip endpoint
private fun handleIpExchange(session: IHTTPSession): Response {
val clientIp = session.remoteIpAddress
val serverIp = getServerIpAddress() // Custom method to get server IP (or hardcode)
Log.d(TAG, "Client IP: $clientIp, Server IP: $serverIp")
CoroutineScope(Dispatchers.Main).launch {
activity.toggleVisibility(isDeviceConnected = true)
}
val ipResponseJson = """
{
"client_ip": "$clientIp",
"server_ip": "$serverIp"
}
""".trimIndent()
return newFixedLengthResponse(Response.Status.OK, "application/json", ipResponseJson)
}
private fun getServerIpAddress(): String? {
return InternetUtil.getLocalIpAddress() // Replace with actual method to get IP address dynamically
}
private fun postUpload2(session: IHTTPSession): Response {
println("Received HTTP POST with upload body...")
// Check if the content type is multipart/form-data
val contentType = session.headers["content-type"]
if (contentType == null || !contentType.contains("multipart/form-data")) {
return newFixedLengthResponse(Response.Status.BAD_REQUEST, "application/json", "{\"error\": \"Invalid content type\"}")
}
// Get the content length for progress tracking
val contentLength = session.headers["content-length"]?.toLongOrNull() ?: 0L
if (contentLength == 0L) {
return newFixedLengthResponse(Response.Status.BAD_REQUEST, "application/json", "{\"error\": \"Invalid content length\"}")
}
// Create a buffer for reading chunks of the input stream
val bufferSize = 8192
val buffer = ByteArray(bufferSize)
var bytesRead: Int
var totalBytesRead = 0L
try {
// Extract the input stream from the session
val inputStream = session.inputStream
val tempFile = File(activity.cacheDir, "uploaded_temp_file")
// Open output stream to write to a temporary file
tempFile.outputStream().buffered().use { outputStream ->
// Read the input stream in chunks and write to the file
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
outputStream.write(buffer, 0, bytesRead)
totalBytesRead += bytesRead
// Calculate the progress percentage
val progress = (totalBytesRead * 100 / contentLength).toInt()
Log.d(TAG, "Upload progress: $progress%")
}
inputStream.close()
outputStream.flush()
return newFixedLengthResponse(Response.Status.OK, "application/json", "{\"message\": \"File uploaded successfully\", \"file\": \"\"}")
}
} catch (e: IOException) {
e.printStackTrace()
return newFixedLengthResponse(Response.Status.INTERNAL_ERROR, "application/json", "{\"error\": \"Failed to parse multipart data\"}")
}
}
companion object {
private const val TAG = "NanoHttpServer"
}
java.net.SocketTimeoutException : Время чтения истекло
Подробнее здесь: https://stackoverflow.com/questions/790 ... pd-android