blob: 7aae8e3b595aab3d22cf342393f35870e4b3c287 [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.testutils
import android.net.Uri
import com.android.net.module.util.ArrayTrackRecord
import fi.iki.elonen.NanoHTTPD
/**
* A minimal HTTP server running on a random available port.
*
* @param host The host to listen to, or null to listen on all hosts
*/
class TestHttpServer(host: String? = null) : NanoHTTPD(host, 0 /* auto-select the port */) {
// Map of URL path -> HTTP response code
private val responses = HashMap<Request, Response>()
/**
* A record of all requests received by the server since it was started.
*/
val requestsRecord = ArrayTrackRecord<Request>()
/**
* A request received by the test server.
*/
data class Request(
val path: String,
val method: Method = Method.GET,
val queryParameters: String = ""
) {
/**
* Returns whether the specified [Uri] matches parameters of this request.
*/
fun matches(uri: Uri) = (uri.path ?: "") == path && (uri.query ?: "") == queryParameters
}
/**
* Add a response for GET requests with the path and query parameters of the specified [Uri].
*/
fun addResponse(
uri: Uri,
statusCode: Response.IStatus,
locationHeader: String? = null,
content: String = ""
) {
addResponse(Request(uri.path
?: "", Method.GET, uri.query ?: ""),
statusCode, locationHeader, content)
}
/**
* Add a response for the given request.
*/
fun addResponse(
request: Request,
statusCode: Response.IStatus,
locationHeader: String? = null,
content: String = ""
) {
val response = newFixedLengthResponse(statusCode, "text/plain", content)
locationHeader?.let { response.addHeader("Location", it) }
responses[request] = response
}
override fun serve(session: IHTTPSession): Response {
val request = Request(session.uri
?: "", session.method, session.queryParameterString ?: "")
requestsRecord.add(request)
// Default response is a 404
return responses[request] ?: super.serve(session)
}
}