Skip to content

Commit

Permalink
Websocket adapter supports uploading http api
Browse files Browse the repository at this point in the history
  • Loading branch information
ryoii committed Nov 27, 2023
1 parent 2842907 commit 447bb49
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import net.mamoe.mirai.api.http.adapter.http.plugin.Authorization
import net.mamoe.mirai.api.http.adapter.http.plugin.GlobalExceptionHandler
import net.mamoe.mirai.api.http.adapter.http.plugin.HttpRouterMonitor
import net.mamoe.mirai.api.http.adapter.internal.serializer.BuiltinJsonSerializer
import net.mamoe.mirai.api.http.adapter.uploading.uploadingRouter
import net.mamoe.mirai.api.http.context.MahContextHolder


Expand Down Expand Up @@ -52,4 +53,5 @@ fun Application.httpModule(adapter: HttpAdapter) {
fileRouter()
commandRouter()
announcementRouter()
uploadingRouter()
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@

package net.mamoe.mirai.api.http.adapter.http.router

import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import net.mamoe.mirai.api.http.adapter.common.IllegalParamException
import net.mamoe.mirai.api.http.adapter.http.dto.CountDTO
import net.mamoe.mirai.api.http.adapter.internal.action.*
import net.mamoe.mirai.api.http.adapter.internal.consts.Paths
import net.mamoe.mirai.api.http.adapter.internal.dto.EventListRestfulResult
import net.mamoe.mirai.api.http.adapter.internal.dto.IntRestfulResult
import net.mamoe.mirai.api.http.util.openAsStream

/**
* 消息路由
Expand Down Expand Up @@ -101,51 +98,6 @@ internal fun Application.messageRouter() = routing {
*/
httpAuthedPost(Paths.sendImageMessage, respondDTOStrategy(::onSendImageMessage))

/**
* 上传图片
*/
httpAuthedMultiPart(Paths.uploadImage) { session, parts ->
val type = parts.value("type")
val url = parts.valueOrNull("url")
val stream = if (url != null) {
url.openAsStream()
} else {
val f = parts.file("img") ?: throw IllegalParamException("缺少参数 img")
f.streamProvider()
}

val ret = onUploadImage(session, stream, type)
call.respond(ret)
}

/**
* 上传语音
*/
httpAuthedMultiPart(Paths.uploadVoice) { session, parts ->
val type = parts.value("type")
val url = parts.valueOrNull("url")
val stream = if (url != null) {
url.openAsStream()
} else {
val f = parts.file("voice") ?: throw IllegalParamException("缺少参数 voice")
f.streamProvider()
}
val ret = onUploadVoice(session, stream, type)
call.respond(ret)
}

/**
* 上传短视频
*/
httpAuthedMultiPart(Paths.uploadShortVideo) { session, parts ->
val type = parts.value("type")
val thumbnail = parts.file("thumbnail")?.run { streamProvider() } ?: throw IllegalParamException("缺少参数 thumbnail")
val video = parts.file("video")?.run{ streamProvider() } ?: throw IllegalParamException("缺少参数 video")

val ret = onUploadShortVideo(session, thumbnail, video, type)
call.respond(ret)
}

/**
* 撤回消息
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/

package net.mamoe.mirai.api.http.adapter.uploading

import io.ktor.http.content.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import net.mamoe.mirai.api.http.adapter.common.IllegalParamException
import net.mamoe.mirai.api.http.adapter.http.router.file
import net.mamoe.mirai.api.http.adapter.http.router.httpAuthedMultiPart
import net.mamoe.mirai.api.http.adapter.http.router.value
import net.mamoe.mirai.api.http.adapter.http.router.valueOrNull
import net.mamoe.mirai.api.http.adapter.internal.action.onUploadImage
import net.mamoe.mirai.api.http.adapter.internal.action.onUploadShortVideo
import net.mamoe.mirai.api.http.adapter.internal.action.onUploadVoice
import net.mamoe.mirai.api.http.adapter.internal.consts.Paths
import net.mamoe.mirai.api.http.util.openAsStream

/**
* 上传相关路由
*/
internal fun Application.uploadingRouter() = routing {

/**
* 上传图片
*/
httpAuthedMultiPart(Paths.uploadImage) { session, parts ->
val type = parts.value("type")
val url = parts.valueOrNull("url")
val stream = if (url != null) {
url.openAsStream()
} else {
val f = parts.file("img") ?: throw IllegalParamException("缺少参数 img")
f.streamProvider()
}

val ret = onUploadImage(session, stream, type)
call.respond(ret)
}

/**
* 上传语音
*/
httpAuthedMultiPart(Paths.uploadVoice) { session, parts ->
val type = parts.value("type")
val url = parts.valueOrNull("url")
val stream = if (url != null) {
url.openAsStream()
} else {
val f = parts.file("voice") ?: throw IllegalParamException("缺少参数 voice")
f.streamProvider()
}
val ret = onUploadVoice(session, stream, type)
call.respond(ret)
}

/**
* 上传短视频
*/
httpAuthedMultiPart(Paths.uploadShortVideo) { session, parts ->
val type = parts.value("type")
val thumbnail = parts.file("thumbnail")?.run { streamProvider() } ?: throw IllegalParamException("缺少参数 thumbnail")
val video = parts.file("video")?.run{ streamProvider() } ?: throw IllegalParamException("缺少参数 video")

val ret = onUploadShortVideo(session, thumbnail, video, type)
call.respond(ret)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
* Copyright 2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
Expand All @@ -17,6 +17,7 @@ import kotlinx.coroutines.channels.SendChannel
import net.mamoe.mirai.api.http.adapter.internal.dto.VerifyRetDTO
import net.mamoe.mirai.api.http.adapter.internal.serializer.toJson
import net.mamoe.mirai.api.http.adapter.internal.serializer.toJsonElement
import net.mamoe.mirai.api.http.adapter.uploading.uploadingRouter
import net.mamoe.mirai.api.http.adapter.ws.WebsocketAdapter
import net.mamoe.mirai.api.http.adapter.ws.dto.WsOutgoing
import net.mamoe.mirai.api.http.adapter.ws.extension.FrameLogExtension
Expand All @@ -34,6 +35,7 @@ fun Application.websocketRouteModule(wsAdapter: WebsocketAdapter) {
}
}
wsRouter(wsAdapter)
uploadingRouter()
}

/**
Expand Down
38 changes: 38 additions & 0 deletions mirai-api-http/src/test/kotlin/integration/ktor/Uploading.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/

package integration.ktor

import framework.testWebsocketApplication
import io.ktor.client.request.forms.*
import io.ktor.http.*
import net.mamoe.mirai.api.http.adapter.internal.consts.Paths
import net.mamoe.mirai.api.http.adapter.uploading.uploadingRouter
import kotlin.test.Test
import kotlin.test.assertEquals

class UploadingRouterConflict {

@Test
fun testUploadingRouterConflict() = testWebsocketApplication {
// no conflict
installHttpAdapter()
application {
// no conflict
uploadingRouter()
}

// response success
client.submitFormWithBinaryData(Paths.httpPath(Paths.uploadImage), formData {
append("path", "/")
}).also {
assertEquals(HttpStatusCode.OK, it.status)
}
}
}

0 comments on commit 447bb49

Please sign in to comment.