Is wireMock.Net able to handle json files from folders under "__admin/mappings" directory? - wiremock

I've developed a project using asp.net core 2.0 + wiremock.net. Currently, I'm able to handle json files under "__admin/mappings" directory only. However, I have several json files and because of that, I'd like to add one more folder under the "mappings" directory, for example "__admin/mappings/{anotherFolder}".
What I have:
__admin/mappings/first.json
__admin/mappings/second.json
What I would like to have:
__admin/mappings/folder_A/first.json
__admin/mappings/folder_A/second.json
__admin/mappings/folder_B/first.json
__admin/mappings/folder_B/second.json
I've tried to add one more folder under the "mappings" folder, but when I tried to reach the json route, I got a message "No matching mapping found". Is there any way to handle json files from different directories?

I had to implement my own FileSystemHandler object and pass it on the FluentMockServerSettings constructor:
var stub = FluentMockServer.Start(
new FluentMockServerSettings
{
Urls = new[] {"http://+:5001" },
StartAdminInterface = true,
ReadStaticMappings = true,
WatchStaticMappings = true,
**FileSystemHandler = new CustomFileSystemFileHandler()**
}
);

You can use settings now
"WatchStaticMappingsInSubdirectories": true

Related

How to upload to a specific folder in the Google Drive GoogleAPIs v3 in Dart?

I'm want to upload images to a specific folder.
This is the function i'm using right now to upload my files, it uploads them the to main folder:
import 'package:googleapis/drive/v3.dart' as driveV3;
Future upload(File file) async {
var client = await getHttpClient();
var drive = driveV3.DriveApi(client);
var response = await drive.files.create(
driveV3.File()..name = p.basename(file.absolute.path),
uploadMedia: driveV3.Media(file.openRead(), file.lengthSync())
);
}
What i want is a way to upload ALWAYS to a folder that can be created at the first time or something like that. what do i need to modify in the above function so i can specify a folder name EX: MyFolder and always uploads to it?
You are looking for the parents of the File class
This property takes a list of String. These strings are the folders you want to upload the file to. As it seems, a file can be uploaded in multiple folders.
So your code should look something like this:
Future upload(File file) async {
var client = await getHttpClient();
var drive = driveV3.DriveApi(client);
file.parents = ["folder_id"];
var response = await drive.files.create(
driveV3.File()..name = p.basename(file.absolute.path),
uploadMedia: driveV3.Media(file.openRead(), file.lengthSync())
);
}
On the documentation I quote:
The IDs of the parent folders which contain the file. If not specified
as part of a create request, the file will be placed directly in the
user's My Drive folder. If not specified as part of a copy request,
the file will inherit any discoverable parents of the source file.
Update requests must use the addParents and removeParents parameters
to modify the parents list.

PlayFramework 2.3.x: Access public folder using URL with Play and Scala

I am uploading a videos and images using web-service and save the images in our application. When i save the files, the files are save on root of application folder. I want to access those images and videos with localhost url, like: I upload the file and save under app-root/upload/image.jpg. In my route mapping file, i declare routing as below:
GET /uploads/ staticDir:/upload
As define in Play Documentation. But still getting an compile time error: Controller method call expected. I want to access image like this http://localhost:9999/uploads/image.jpg
Well... One way of doing this is by adding following routes,
GET /uploads/*file controllers.Assets.at(path="/uploads", file)
But, it will interfere with the reverse-routing of already existing route which is,
GET /assets/*file controllers.Assets.at(path="/public", file)
And then you will have to use your these two assets routes as - #route.Assets.at("public", filename) and #route.Assets.at("uploads", filename) which means all your templates which use you public assets route as - #route.Assets.at(filename) will have to be changed. Which can be a hassle in an existing big project.
You can avoid this by using following method,
Create another controller as,
package controllers
object FileServer extends Controller {
def serveUploadedFiles1 = controllers.Assets.at( dicrectoryPath, file, false )
// Or... following is same as above
def serveUploadedFiles2( file: String ) = Action.async {
implicit request => {
val dicrectoryPath = "/uploads"
controllers.Assets.at( dicrectoryPath, file, false ).apply( request )
}
}
}
The above should have worked... but seems like play does a lot of meta-data checking on the requested "Assets" which somehow results in empty results for all /uploads/filename requests. I tried to look into the play-source code to check, but it seems like it may take sometime to figure it out.
So I think we can make do with following simpler method ( It can be refined further in so many ways.).
object FileServer extends Controller {
import play.api.http.ContentTypes
import play.api.libs.MimeTypes
import play.api.libs.iteratee.Enumerator
import play.api.libs.concurrent.Execution.Implicits.defaultContext
def serveUploadedFiles(file: String) = Action { implicit request =>
val fileResUri = "uploads/"+file
val mimeType: String = MimeTypes.forFileName( fileResUri ).fold(ContentTypes.BINARY)(addCharsetIfNeeded)
val serveFile = new java.io.File(fileResUri)
if( serveFile.exists() ){
val fileContent: Enumerator[Array[Byte]] = Enumerator.fromFile( serveFile )
//Ok.sendFile(serveFile).as( mimeType )
val response = Result(
ResponseHeader(
OK,
Map(
CONTENT_LENGTH -> serveFile.length.toString,
CONTENT_TYPE -> mimeType
)
),
fileContent
)
response
}
else {
NotFound
}
}
def addCharsetIfNeeded(mimeType: String): String =
if (MimeTypes.isText(mimeType)) s"$mimeType; charset=$defaultCharSet" else mimeType
lazy val defaultCharSet = config(_.getString("default.charset")).getOrElse("utf-8")
def config[T](lookup: Configuration => Option[T]): Option[T] = for {
app <- Play.maybeApplication
value <- lookup(app.configuration)
} yield value
}
But this method will cause some troubles in case of packaged-build deployments.
Which means, using the Play's Asset thing would be wiser choice. So looking again, the controllers.Assets.at which is actually controllers.Assets.assetAt uses this method at one place,
def resource(name: String): Option[URL] = for {
app <- Play.maybeApplication
resource <- app.resource(name)
} yield resource
Which means, it tries to locate the resource in the directories which are part of application's classpath and our uploads folder sure is not one of them. So... we can make play's Assets.at thingy work by adding uploads to classpath.
But... thinking again... If I recall all folders in the classpath are supposed to be packaged in the package to be deployed in-case of packaged-build deployments. And uploaded things will be created by the users, which means they should not be a part of package. Which again means... we should not be trying to access our uploaded things using Play's Assets.at thingy.
So... I think we are better off using our own simpler rudimentary implementation of serveUploadedFiles.
Now add a route in route file as,
GET /uploads/*file controllers.FileServer.serveUploadedFiles( file:String )
Also... Keep in mind that you should not be thinking of using play to serve your uploaded assets. Please use nginx or something similar.

Serving static /public/ file from Play 2 Scala controller

What is the preferred method to serve a static file from a Play Framework 2 Scala controller?
The file is bundled with my application, so it's not possible to hardcode a filesystem absolute /path/to/the/file, because its location depends on where the Play app happens to be installeld.
The file is placed in the public/ dir, but not in app/assets/, because I don't want Play to compile it.
(The reason I don't simply add a route to that file, is that one needs to login before accessing that file, otherwise it's of no use.)
Here is what I've done so far, but this breaks on my production server.
object Application ...
def viewAdminPage = Action ... {
... authorization ...
val adminPageFile = Play.getFile("/public/admin/index.html")
Ok.sendFile(adminPageFile, inline = true)
}
And in my routes file, I have this line:
GET /-/admin/ controllers.Application.viewAdminPage
The problem is that on my production server, this error happens:
FileNotFoundException: app1/public/admin/index.html
Is there some other method, rather than Play.getFile and OK.sendFile, to specify which file to serve? That never breaks in production?
(My app is installed in /some-dir/app1/ and I start it from /some-dir/ (without app1/) — perhaps everything would work if I instead started the app from /some-dir/app1/. But I'd like to know how one "should" do, to serve a static file from inside a controller? So that everything always works also on the production servers, regardless of from where I happen to start the application)
Check Streaming HTTP responses doc
def index = Action {
Ok.sendFile(
content = new java.io.File("/tmp/fileToServe.pdf"),
fileName = _ => "termsOfService.pdf"
)
}
You can add some random string to the fileName (individual for each logged user) to avoid sharing download link between authenticated and non-authinticated users and also make advanced download stats.
I did this: (but see the Update below!)
val fileUrl: java.net.URL = this.getClass().getResource("/public/admin/file.html")
val file = new java.io.File(adminPageUrl.toURI())
Ok.sendFile(file, inline = true)
(this is the controller, which is (and must be) located in the same package as the file that's being served.)
Here is a related question: open resource with relative path in java
Update
Accessing the file via an URI causes an error: IllegalArgumentException: URI is not hierarchical, if the file is then located inside a JAR, which is the case if you run Play like so: play stage and then target/start.
So instead I read the file as a stream, converted it to a String, and sent that string as HTML:
val adminPageFileString: String = {
// In prod builds, the file is embedded in a JAR, and accessing it via
// an URI causes an IllegalArgumentException: "URI is not hierarchical".
// So use a stream instead.
val adminPageStream: java.io.InputStream =
this.getClass().getResourceAsStream("/public/admin/index.html")
io.Source.fromInputStream(adminPageStream).mkString("")
}
...
return Ok(adminPageFileString) as HTML
Play has a built-in method for this:
Ok.sendResource("public/admin/file.html", classLoader)
You can obtain a classloader from an injected Environment with environment.classLoader or from this.getClass.getClassLoader.
The manual approach for this is the following:
val url = Play.resource(file)
url.map { url =>
val stream = url.openStream()
val length = stream.available
val resourceData = Enumerator.fromStream(stream)
val headers = Map(
CONTENT_LENGTH -> length.toString,
CONTENT_TYPE -> MimeTypes.forFileName(file).getOrElse(BINARY),
CONTENT_DISPOSITION -> s"""attachment; filename="$name"""")
SimpleResult(
header = ResponseHeader(OK, headers),
body = resourceData)
The equivalent using the assets controller is this:
val name = "someName.ext"
val response = Assets.at("/public", name)(request)
response
.withHeaders(CONTENT_DISPOSITION -> s"""attachment; filename="$name"""")
Another variant, without using a String, but by streaming the file content:
def myStaticRessource() = Action { implicit request =>
val contentStream = this.getClass.getResourceAsStream("/public/content.html")
Ok.chunked(Enumerator.fromStream(contentStream)).as(HTML)
}

Upload more than one file with the same filename in a form, using Zend Framework

I've got a form where the user can upload 2 pictures. So, I called this code twice, one for each picture:
$upload = new Zend_File_Transfer_Adapter_Http();
$upload->addValidator('Count', true, array(1, 1))
->addValidator('Size', false, self::MAX_FILE_SIZE)
->addValidator('ImageSize', false, array('minwidth' => $minWidth))
->addValidator('MimeType', true,
array('image/gif', 'image/jpeg', 'image/png'))
->setDestination(Divescover_AssetManager::getUploadDir());
// We pass filename as parameter to receive so it can manage
// multiple files
if (!$upload->receive($filename)) {
return array('pic' => $upload->getMessages());
}
But when the user uploads the same picture in both "picture selectors" I get this error:-
File 'picture_main' was illegally uploaded. This could be a possible attack.
I know this is because both files have the same name. I've tried to rename the files using the rename filter but it did not work.
I'd like to solve this problem, but I do need to get both the 2 pictures even if they are the same.

How to reach local files with an ajax call in phonegap?

i Have this piece of code for load a json file stored in the same directory of phonegap ( iPhone ) project ( usually in the "www" folder ), how can i reach "routes.json" ?. My project have this tree folder:
__www/
___index.html
___index.json ( where is located this code )
___routes.json*
store: new Ext.data.Store({
model : 'routes',
proxy: {
type: 'ajax',
url : 'file://??????/www/routes.json',
reader: {
type: 'json'
}
},
autoLoad: true
})
Treat PhoneGap's www directory like you would a directory on your server. You can create as many sub-folders as you like, and you would reference files with relative links.
As YDL mentioned, if you're trying to access index.json and it resides at the root level of the www folder, you would use: index.json. As another example, if you had a sub-folder called data that housed all your json files, you would use: data/index.json.
I think that this is a bug in the Sencha Touch Ext.data.Proxy implementation. I spent a couple hours trying to get this work and was unsuccessful. It took me less than 5 minutes to implement it using jQuery.
//Initialize the Store
new Ext.data.Store(
{
model: "Routes",
storeId: "Routes",
//The Proxy isn't used but it is a required configuration option
proxy: {
type: 'ajax'
}
});
//Populate the store using jQuery.get()
$.get('routes.json',
function(data, status, jqXHR) {
if(status == "success") {
var store = Ext.StoreMgr.get('Routes');
store.loadData(data);
}
});