Cleaning repo
This commit is contained in:
84
.gitignore
vendored
Normal file
84
.gitignore
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
##############################
|
||||
## Java
|
||||
##############################
|
||||
.mtj.tmp/
|
||||
*.class
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.nar
|
||||
hs_err_pid*
|
||||
|
||||
##############################
|
||||
## Maven
|
||||
##############################
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
pom.xml.bak
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
##############################
|
||||
## Gradle
|
||||
##############################
|
||||
bin/
|
||||
build/
|
||||
.gradle
|
||||
.gradletasknamecache
|
||||
gradle-app.setting
|
||||
!gradle-wrapper.jar
|
||||
|
||||
##############################
|
||||
## IntelliJ
|
||||
##############################
|
||||
out/
|
||||
.idea/
|
||||
.idea_modules/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
##############################
|
||||
## Eclipse
|
||||
##############################
|
||||
.settings/
|
||||
bin/
|
||||
tmp/
|
||||
.metadata
|
||||
.classpath
|
||||
.project
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.loadpath
|
||||
.factorypath
|
||||
|
||||
##############################
|
||||
## NetBeans
|
||||
##############################
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
|
||||
##############################
|
||||
## Visual Studio Code
|
||||
##############################
|
||||
.vscode/
|
||||
.code-workspace
|
||||
|
||||
##############################
|
||||
## OS X
|
||||
##############################
|
||||
.DS_Store
|
||||
4
README.md
Normal file
4
README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# EndPoint: API Tester
|
||||
This project replace the ugly [cURLing](https://github.com/alexlegarnd/cURLing)
|
||||
|
||||
It require Gluon JavaFX 14 and Java 14
|
||||
362
javafx.bootstrap/.gitignore
vendored
Normal file
362
javafx.bootstrap/.gitignore
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
31
javafx.bootstrap/javafx.bootstrap.sln
Normal file
31
javafx.bootstrap/javafx.bootstrap.sln
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30503.244
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "javafx.bootstrap", "javafx.bootstrap\javafx.bootstrap.vcxproj", "{B546CB97-CDCE-4317-8AAD-73E76BD19003}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B546CB97-CDCE-4317-8AAD-73E76BD19003}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B546CB97-CDCE-4317-8AAD-73E76BD19003}.Debug|x64.Build.0 = Debug|x64
|
||||
{B546CB97-CDCE-4317-8AAD-73E76BD19003}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B546CB97-CDCE-4317-8AAD-73E76BD19003}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B546CB97-CDCE-4317-8AAD-73E76BD19003}.Release|x64.ActiveCfg = Release|x64
|
||||
{B546CB97-CDCE-4317-8AAD-73E76BD19003}.Release|x64.Build.0 = Release|x64
|
||||
{B546CB97-CDCE-4317-8AAD-73E76BD19003}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B546CB97-CDCE-4317-8AAD-73E76BD19003}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0CDBFE75-E4C2-4545-9553-310226645509}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
71
javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc
Normal file
71
javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc
Normal file
@@ -0,0 +1,71 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON2 ICON "C:\\Users\\robof\\Downloads\\icon.ico"
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
157
javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.vcxproj
Normal file
157
javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.vcxproj
Normal file
@@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{b546cb97-cdce-4317-8aad-73e76bd19003}</ProjectGuid>
|
||||
<RootNamespace>javafxbootstrap</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="javafx.bootstrap.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\..\..\Downloads\icon.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="javafx.bootstrap.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="..\..\..\..\Downloads\icon.ico">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
32
javafx.bootstrap/javafx.bootstrap/main.cpp
Normal file
32
javafx.bootstrap/javafx.bootstrap/main.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <string>
|
||||
#pragma comment(lib,"user32.lib")
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int iCmdShow)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
LPTSTR command = _tcsdup(TEXT(".\\runtime\\bin\\javaw.exe --module-path \".\\lib\" --add-modules javafx.controls,javafx.fxml -jar .\\app\\EndPoint.jar"));
|
||||
if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
||||
{
|
||||
CloseHandle(&pi.hProcess);
|
||||
CloseHandle(&pi.hThread);
|
||||
int msgboxID = MessageBox(
|
||||
NULL,
|
||||
TEXT("Unable to start the JVM. Try reinstalling the program to fix this problem."),
|
||||
TEXT("EndPoint bootstrap"),
|
||||
MB_ICONHAND | MB_OK | MB_DEFBUTTON1
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
CloseHandle(&pi.hProcess);
|
||||
CloseHandle(&pi.hThread);
|
||||
return 0;
|
||||
}
|
||||
16
javafx.bootstrap/javafx.bootstrap/resource.h
Normal file
16
javafx.bootstrap/javafx.bootstrap/resource.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by javafx.bootstrap.rc
|
||||
//
|
||||
#define IDI_ICON2 102
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
6
src/META-INF/MANIFEST.MF
Normal file
6
src/META-INF/MANIFEST.MF
Normal file
@@ -0,0 +1,6 @@
|
||||
Manifest-Version: 1.0
|
||||
Main-Class: ovh.alexisdelhaie.endpoint.Main
|
||||
Class-Path: src.zip javafx-swt.jar javafx.web.jar javafx.base.jar javafx
|
||||
.fxml.jar javafx.media.jar javafx.swing.jar javafx.controls.jar javafx.
|
||||
graphics.jar
|
||||
|
||||
413
src/ovh/alexisdelhaie/endpoint/Controller.java
Normal file
413
src/ovh/alexisdelhaie/endpoint/Controller.java
Normal file
@@ -0,0 +1,413 @@
|
||||
package ovh.alexisdelhaie.endpoint;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import ovh.alexisdelhaie.endpoint.http.HttpClient;
|
||||
import ovh.alexisdelhaie.endpoint.http.Request;
|
||||
import ovh.alexisdelhaie.endpoint.http.RequestBuilder;
|
||||
import ovh.alexisdelhaie.endpoint.http.Response;
|
||||
import ovh.alexisdelhaie.endpoint.impl.EditCell;
|
||||
import ovh.alexisdelhaie.endpoint.model.Param;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Controller implements Initializable {
|
||||
|
||||
private enum StatusColor {
|
||||
INFORMATION("#53baf5"),
|
||||
SUCCESS("#7ccf16"),
|
||||
REDIRECTION("#b153f5"),
|
||||
ERROR_CLIENT("#f5ca53"),
|
||||
ERROR_SERVER("#f55353"),
|
||||
DEFAULT("BLACK");
|
||||
|
||||
private final String hex;
|
||||
|
||||
StatusColor(String s) {
|
||||
hex = s;
|
||||
}
|
||||
|
||||
public String getHex() {
|
||||
return hex;
|
||||
}
|
||||
}
|
||||
|
||||
private enum RequestTab {
|
||||
PARAMS(0),
|
||||
AUTHORIZATION(1),
|
||||
HEADERS(2),
|
||||
BODY(3),
|
||||
RESPONSE(4);
|
||||
|
||||
private final int index;
|
||||
|
||||
RequestTab (int i) { index = i; }
|
||||
public int getIndex() { return index; }
|
||||
}
|
||||
|
||||
@FXML
|
||||
private ChoiceBox<String> httpMethod;
|
||||
@FXML
|
||||
private TabPane tabs;
|
||||
@FXML
|
||||
private TextField requestInput;
|
||||
@FXML
|
||||
private Pane runningIndicatorPane;
|
||||
|
||||
private Stage primaryStage;
|
||||
private HashMap<Integer, String> requests;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
requests = new HashMap<>();
|
||||
String[] method = { "GET", "POST", "HEAD", "PUT", "DELETE" };
|
||||
httpMethod.setItems(FXCollections.observableArrayList(method));
|
||||
httpMethod.setValue(method[0]);
|
||||
tabs.getSelectionModel().selectedItemProperty().addListener(
|
||||
(ov, t, t1) -> requestInput.setText((t1 != null) ? requests.get(t1.hashCode()) : "")
|
||||
);
|
||||
createNewTab();
|
||||
}
|
||||
|
||||
private Tab newTab() {
|
||||
SplitPane sp = new SplitPane();
|
||||
|
||||
Tab params = new Tab("Params", createParamTable());
|
||||
Tab auth = new Tab("Authorization");
|
||||
Tab headers = new Tab("Headers", createParamTable());
|
||||
Tab body = new Tab("Body", new TextArea());
|
||||
Tab response = new Tab("Response", createResponseTab());
|
||||
|
||||
TabPane options = new TabPane();
|
||||
TextArea ta = new TextArea();
|
||||
|
||||
options.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
|
||||
options.getTabs().addAll(params, auth, headers, body, response);
|
||||
sp.getItems().add(options);
|
||||
sp.getItems().add(ta);
|
||||
sp.setOrientation(Orientation.VERTICAL);
|
||||
|
||||
return new Tab("untitled", sp);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ScrollPane createResponseTab() {
|
||||
ScrollPane sp = new ScrollPane();
|
||||
Pane p = new Pane();
|
||||
sp.setContent(p);
|
||||
try {
|
||||
Parent xml = FXMLLoader.load(getClass().getResource("responsetab.fxml"));
|
||||
p.getChildren().add(xml);
|
||||
TableView<Param> headers = (TableView<Param>) p.lookup("#headers");
|
||||
headers.getColumns().get(0).setCellValueFactory(new PropertyValueFactory<>("name"));
|
||||
headers.getColumns().get(1).setCellValueFactory(new PropertyValueFactory<>("value"));
|
||||
} catch (IOException e) {
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
private TableView<Param> createParamTable() {
|
||||
TableView<Param> paramsTable = new TableView<>();
|
||||
|
||||
TableColumn<Param, String> name = createColumn("Name", Param::name);
|
||||
TableColumn<Param, String> value = createColumn("Value", Param::value);
|
||||
|
||||
name.prefWidthProperty().bind(paramsTable.widthProperty().multiply(0.5));
|
||||
value.prefWidthProperty().bind(paramsTable.widthProperty().multiply(0.5));
|
||||
|
||||
name.setOnEditCommit(t -> {
|
||||
TableView<Param> tv = t.getTableView();
|
||||
t.getRowValue().name().set(t.getNewValue());
|
||||
manageEmptyCells(t, tv);
|
||||
});
|
||||
value.setOnEditCommit(t -> {
|
||||
TableView<Param> tv = t.getTableView();
|
||||
t.getRowValue().value().set(t.getNewValue());
|
||||
manageEmptyCells(t, tv);
|
||||
});
|
||||
|
||||
paramsTable.getColumns().add(name);
|
||||
paramsTable.getColumns().add(value);
|
||||
|
||||
paramsTable.setEditable(true);
|
||||
paramsTable.getItems().add(new Param());
|
||||
|
||||
return paramsTable;
|
||||
}
|
||||
|
||||
private void manageEmptyCells(TableColumn.CellEditEvent<Param, String> t, TableView<Param> tv) {
|
||||
if (t.getRowValue().isEmpty() && tv.getItems().size() > 1) {
|
||||
tv.getItems().remove(t.getRowValue());
|
||||
}
|
||||
if (!tv.getItems().get(tv.getItems().size() - 1).isEmpty()) {
|
||||
tv.getItems().add(new Param());
|
||||
}
|
||||
requestInput.setText(URLGenerator.processNewUrl(getParamsMap(), requestInput.getText()));
|
||||
}
|
||||
|
||||
private TableColumn<Param, String> createColumn(String title, Function<Param, StringProperty> property) {
|
||||
TableColumn<Param, String> col = new TableColumn<>(title);
|
||||
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
|
||||
|
||||
col.setCellFactory(column -> EditCell.createStringEditCell());
|
||||
return col ;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void start() {
|
||||
runningIndicatorPane.setVisible(true);
|
||||
new Thread(() -> {
|
||||
final String method = httpMethod.getValue();
|
||||
Optional<TextArea> textArea = getCurrentTextArea();
|
||||
Optional<Response> response = Optional.empty();
|
||||
if (textArea.isPresent()) {
|
||||
try {
|
||||
Request r = new RequestBuilder(requestInput.getText())
|
||||
.setCustomHeaders(getCustomHeaders())
|
||||
.build();
|
||||
HttpClient hc = new HttpClient();
|
||||
switch (method) {
|
||||
case "GET" -> response = hc.get(r);
|
||||
case "POST" -> response = hc.post(r, getBody());
|
||||
case "PUT" -> response = hc.put(r, getBody());
|
||||
case "DELETE" -> response = hc.delete(r);
|
||||
case "HEAD" -> response = hc.head(r);
|
||||
}
|
||||
if (response.isPresent()) {
|
||||
final Response res = response.get();
|
||||
Platform.runLater(() -> {
|
||||
textArea.get().setStyle(null);
|
||||
textArea.get().setText(res.getBody());
|
||||
updateResponseTab(res);
|
||||
setSelectedTab(RequestTab.RESPONSE);
|
||||
});
|
||||
}
|
||||
} catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
|
||||
System.err.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
textArea.ifPresent(area -> Platform.runLater(() -> {
|
||||
resetResponseTab();
|
||||
area.setStyle("-fx-text-fill: red");
|
||||
area.setText("Somethings went wrong: " + e.getMessage());
|
||||
}));
|
||||
} finally {
|
||||
Platform.runLater(() -> {
|
||||
runningIndicatorPane.setVisible(false);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
Platform.runLater(() -> {
|
||||
runningIndicatorPane.setVisible(false);
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void updateResponseTab(Response res) {
|
||||
Optional<Tab> responseTab = getCurrentResponseTab();
|
||||
if (responseTab.isPresent()) {
|
||||
Label status = (Label) responseTab.get().getContent().lookup("#status");
|
||||
status.setText(String.format("%s %s", res.getStatusCode(), res.getStatus()));
|
||||
if (res.getStatusCode() >= 100 && res.getStatusCode() < 200) {
|
||||
status.setTextFill(Color.web(StatusColor.INFORMATION.getHex()));
|
||||
} else if (res.getStatusCode() >= 200 && res.getStatusCode() < 300) {
|
||||
status.setTextFill(Color.web(StatusColor.SUCCESS.getHex()));
|
||||
} else if (res.getStatusCode() >= 300 && res.getStatusCode() < 400) {
|
||||
status.setTextFill(Color.web(StatusColor.REDIRECTION.getHex()));
|
||||
} else if (res.getStatusCode() >= 400 && res.getStatusCode() < 500) {
|
||||
status.setTextFill(Color.web(StatusColor.ERROR_CLIENT.getHex()));
|
||||
} else if (res.getStatusCode() >= 500) {
|
||||
status.setTextFill(Color.web(StatusColor.ERROR_SERVER.getHex()));
|
||||
}
|
||||
Label time = (Label) responseTab.get().getContent().lookup("#time");
|
||||
time.setText(String.format("%s ms", res.getTime()));
|
||||
TextArea raw = (TextArea) responseTab.get().getContent().lookup("#raw");
|
||||
raw.setText(res.getRawResponse());
|
||||
TextArea request = (TextArea) responseTab.get().getContent().lookup("#request");
|
||||
request.setText(res.getRequest().getRawRequest());
|
||||
TableView<Param> headers = (TableView<Param>) responseTab.get().getContent().lookup("#headers");
|
||||
headers.getItems().clear();
|
||||
for (Map.Entry<String, String> entry : res.getHeaders().entrySet()) {
|
||||
headers.getItems().add(new Param(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setSelectedTab(RequestTab rt) {
|
||||
Optional<TabPane> options = getRequestOptionsTab();
|
||||
options.ifPresent(tabPane -> tabPane.getSelectionModel().select(rt.getIndex()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void resetResponseTab() {
|
||||
Optional<Tab> responseTab = getCurrentResponseTab();
|
||||
if (responseTab.isPresent()) {
|
||||
Label status = (Label) responseTab.get().getContent().lookup("#status");
|
||||
status.setTextFill(Color.web(StatusColor.DEFAULT.getHex()));
|
||||
status.setText("...");
|
||||
Label time = (Label) responseTab.get().getContent().lookup("#time");
|
||||
time.setText("... ms");
|
||||
TextArea raw = (TextArea) responseTab.get().getContent().lookup("#raw");
|
||||
raw.setText("");
|
||||
TableView<Param> headers = (TableView<Param>) responseTab.get().getContent().lookup("#headers");
|
||||
headers.getItems().clear();
|
||||
}
|
||||
}
|
||||
|
||||
private HashMap<String, String> getCustomHeaders() {
|
||||
HashMap<String, String> result = new HashMap<>();
|
||||
Optional<TabPane> tabs = getRequestOptionsTab();
|
||||
if (tabs.isPresent()) {
|
||||
Node n = tabs.get().getTabs().get(RequestTab.HEADERS.getIndex()).getContent();
|
||||
toHashMap(result, n, true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getBody() {
|
||||
Optional<TabPane> tabs = getRequestOptionsTab();
|
||||
if (tabs.isPresent()) {
|
||||
Node n = tabs.get().getTabs().get(RequestTab.BODY.getIndex()).getContent();
|
||||
if (n instanceof TextArea) {
|
||||
return ((TextArea) n).getText();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private HashMap<String, String> getParamsMap() {
|
||||
HashMap<String, String> result = new HashMap<>();
|
||||
Optional<TabPane> tabs = getRequestOptionsTab();
|
||||
if (tabs.isPresent()) {
|
||||
Node n = tabs.get().getTabs().get(RequestTab.PARAMS.getIndex()).getContent();
|
||||
toHashMap(result, n, false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void toHashMap(HashMap<String, String> result, Node n, boolean lowering) {
|
||||
if (n instanceof TableView) {
|
||||
TableView<Param> tv = (TableView<Param>) n;
|
||||
for (Param p : tv.getItems()) {
|
||||
if (!p.isEmpty()) {
|
||||
String key = (lowering) ? p.getName().toLowerCase() : p.getName();
|
||||
result.put(key, p.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<TabPane> getRequestOptionsTab() {
|
||||
Optional<SplitPane> requestTab = getCurrentRequestTab();
|
||||
if (requestTab.isPresent()) {
|
||||
Node n = requestTab.get().getItems().get(0);
|
||||
if (n instanceof TabPane) {
|
||||
return Optional.of((TabPane) n);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<SplitPane> getCurrentRequestTab() {
|
||||
Node n = tabs.getSelectionModel().getSelectedItem().getContent();
|
||||
if (n instanceof SplitPane) {
|
||||
return Optional.of((SplitPane) n);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<TextArea> getCurrentTextArea() {
|
||||
Optional<SplitPane> requestTab = getCurrentRequestTab();
|
||||
if (requestTab.isPresent()) {
|
||||
Node n = requestTab.get().getItems().get(1);//
|
||||
if (n instanceof TextArea) {
|
||||
return Optional.of((TextArea) n);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<Tab> getCurrentResponseTab() {
|
||||
Optional<TabPane> requestTab = getRequestOptionsTab();
|
||||
if (requestTab.isPresent()) {
|
||||
Tab n = requestTab.get().getTabs().get(RequestTab.RESPONSE.getIndex());
|
||||
return Optional.of(n);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void createNewTab() {
|
||||
new Thread(() -> {
|
||||
Tab t = newTab();
|
||||
requests.put(t.hashCode(), "");
|
||||
Platform.runLater(() -> {
|
||||
tabs.getTabs().add(t);
|
||||
tabs.getSelectionModel().select(t);
|
||||
});
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void setStageAndSetupListeners(Stage s) {
|
||||
primaryStage = s;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void showAboutDialog() {
|
||||
try {
|
||||
Stage dialog = new Stage();
|
||||
Parent xml = FXMLLoader.load(getClass().getResource("about.fxml"));
|
||||
dialog.initOwner(primaryStage);
|
||||
dialog.setScene(new Scene(xml, 677, 365));
|
||||
dialog.setMaxHeight(365);
|
||||
dialog.setMinHeight(365);
|
||||
dialog.setMaxWidth(707);
|
||||
dialog.setMinWidth(707);
|
||||
dialog.setResizable(false);
|
||||
dialog.setTitle("About EndPoint");
|
||||
dialog.getIcons().add( new Image(
|
||||
Controller.class.getResourceAsStream( "icon.png" )));
|
||||
dialog.initModality(Modality.APPLICATION_MODAL);
|
||||
dialog.showAndWait();
|
||||
} catch (IOException e) {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("Cannot initialize About");
|
||||
alert.setHeaderText("There was an error while initializing this dialog");
|
||||
alert.setContentText(e.getMessage());
|
||||
alert.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void requestInputOnKeyPressed() {
|
||||
Tab tab = tabs.getSelectionModel().getSelectedItem();
|
||||
requests.put(tab.hashCode(), requestInput.getText());
|
||||
}
|
||||
|
||||
}
|
||||
32
src/ovh/alexisdelhaie/endpoint/Main.java
Normal file
32
src/ovh/alexisdelhaie/endpoint/Main.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package ovh.alexisdelhaie.endpoint;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class Main extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception{
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("mainwindow.fxml"));
|
||||
Parent root = loader.load();
|
||||
Controller controller = loader.getController();
|
||||
controller.setStageAndSetupListeners(primaryStage);
|
||||
primaryStage.setTitle("EndPoint");
|
||||
primaryStage.setScene(new Scene(root, 1067, 644));
|
||||
primaryStage.setMinWidth(1067);
|
||||
primaryStage.setMinHeight(644);
|
||||
primaryStage.setMaximized(true);
|
||||
primaryStage.getIcons().add( new Image(
|
||||
Main.class.getResourceAsStream( "icon.png" )));
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
}
|
||||
99
src/ovh/alexisdelhaie/endpoint/URLGenerator.java
Normal file
99
src/ovh/alexisdelhaie/endpoint/URLGenerator.java
Normal file
@@ -0,0 +1,99 @@
|
||||
package ovh.alexisdelhaie.endpoint;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class URLGenerator {
|
||||
|
||||
public static final String HTTP_START = "http://";
|
||||
public static final String HTTPS_START = "https://";
|
||||
public static final String[][] SPECIAL_CHARS = new String[][] {
|
||||
{ " ", "%20" }, { "<", "%3C" }, { ">", "%3E" },
|
||||
{ "#", "%23" }, { "{", "%7B" },
|
||||
{ "}", "%7D" }, { "|", "%7C" }, { "\\", "%5C" },
|
||||
{ "^", "%5E" }, { "~", "%7E" }, { "[", "%5B" },
|
||||
{ "]", "%5D" }, { "`", "%60" }, { ";", "%3B" },
|
||||
{ "/", "%2F" }, { "?", "%3F" }, { ":", "%3A" },
|
||||
{ "@", "%40" }, { "=", "%3D" }, { "&", "%26" },
|
||||
{ "$", "%24" }, { "\r", "%0D" }, { "\n", "%0A" }
|
||||
};
|
||||
|
||||
static public String processNewUrl(HashMap<String, String> p, String url) {
|
||||
try {
|
||||
if (!url.startsWith(HTTP_START) && !url.startsWith(HTTPS_START)) {
|
||||
url = HTTP_START + url;
|
||||
}
|
||||
String newUrl = (url.startsWith(HTTPS_START)) ? HTTPS_START : HTTP_START;
|
||||
URL u = new URL(url);
|
||||
newUrl += u.getHost();
|
||||
if (u.getPort() != -1) {
|
||||
newUrl += ":" + u.getPort();
|
||||
}
|
||||
newUrl += (u.getPath().isBlank()) ? "/" : u.getPath();
|
||||
newUrl += generateParamsPart(p);
|
||||
return newUrl;
|
||||
} catch (MalformedURLException e) {
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
public static Map<String, String> getSpecialCharRef() {
|
||||
return Stream.of(SPECIAL_CHARS)
|
||||
.collect(Collectors.toMap(data -> (String) data[0], data -> (String) data[1]));
|
||||
}
|
||||
|
||||
static public String generateParamsPartWithEncoding(HashMap<String, String> p) {
|
||||
String result = "?";
|
||||
for (Map.Entry<String, String> entry : p.entrySet()) {
|
||||
result = new StringBuilder(result)
|
||||
.append(entry.getKey())
|
||||
.append("=")
|
||||
.append(entry.getValue())
|
||||
.append("&").toString();
|
||||
}
|
||||
if (result.equals("?")) {
|
||||
result = "";
|
||||
} else if (result.endsWith("&")) {
|
||||
result = result.substring(0, result.length() - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static public String generateParamsPart(HashMap<String, String> p) {
|
||||
Map<String, String> specialCharRef = getSpecialCharRef();
|
||||
|
||||
String result = "?";
|
||||
for (Map.Entry<String, String> entry : p.entrySet()) {
|
||||
String key = escapeText(entry.getKey(), specialCharRef);
|
||||
String value = escapeText(entry.getValue(), specialCharRef);
|
||||
result = new StringBuilder(result)
|
||||
.append(key)
|
||||
.append("=")
|
||||
.append(value)
|
||||
.append("&").toString();
|
||||
}
|
||||
if (result.equals("?")) {
|
||||
result = "";
|
||||
} else if (result.endsWith("&")) {
|
||||
result = result.substring(0, result.length() - 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static public String escapeText(String s, Map<String, String> scr) {
|
||||
String result = s.replace("%", "%25");
|
||||
for (Map.Entry<String, String> entry : scr.entrySet()) {
|
||||
if (result.contains(entry.getKey())) {
|
||||
result = result.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
43
src/ovh/alexisdelhaie/endpoint/about.fxml
Normal file
43
src/ovh/alexisdelhaie/endpoint/about.fxml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="365.0" prefWidth="707.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Label layoutX="25.0" layoutY="183.0" text="Made with Java 14.0.2 (GUI with JavaFX 15)">
|
||||
<font>
|
||||
<Font size="13.0" />
|
||||
</font></Label>
|
||||
<Label layoutX="25.0" layoutY="147.0" text="Author: Alexis Delhaie (@alexlegarnd)">
|
||||
<font>
|
||||
<Font size="13.0" />
|
||||
</font></Label>
|
||||
<ImageView fitHeight="111.0" fitWidth="707.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<image>
|
||||
<Image url="@banner.png" />
|
||||
</image></ImageView>
|
||||
<Label layoutX="25.0" layoutY="220.0" text="Installer made with Delphi 10.3 Community">
|
||||
<font>
|
||||
<Font size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label layoutX="25.0" layoutY="257.0" text="Installer Bootstrap made with Python 3">
|
||||
<font>
|
||||
<Font size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label layoutX="422.0" layoutY="158.0" text="EndPoint">
|
||||
<font>
|
||||
<Font size="48.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label layoutX="444.0" layoutY="230.0" text="Version 0.1 (Not finished)">
|
||||
<font>
|
||||
<Font size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
BIN
src/ovh/alexisdelhaie/endpoint/banner.png
Normal file
BIN
src/ovh/alexisdelhaie/endpoint/banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
20
src/ovh/alexisdelhaie/endpoint/configuration.fxml
Normal file
20
src/ovh/alexisdelhaie/endpoint/configuration.fxml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.shape.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
|
||||
<AnchorPane prefHeight="556.0" prefWidth="410.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ovh.alexisdelhaie.endpoint.Configuration">
|
||||
<children>
|
||||
<Label layoutX="12.0" layoutY="11.0" text="SSL">
|
||||
<font>
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label layoutX="13.0" layoutY="35.0" text="Allow invalid SSL certificate" />
|
||||
<CheckBox layoutX="381.0" layoutY="31.0" mnemonicParsing="false" />
|
||||
<Line endX="100.0" layoutX="271.0" layoutY="48.0" startX="-100.0" stroke="#bfbfbf" strokeLineCap="ROUND" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
135
src/ovh/alexisdelhaie/endpoint/http/HttpClient.java
Normal file
135
src/ovh/alexisdelhaie/endpoint/http/HttpClient.java
Normal file
@@ -0,0 +1,135 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class HttpClient {
|
||||
|
||||
public final static String CRLF = "\r\n";
|
||||
public final static int DEFAULT_TIMEOUT = 10000;
|
||||
|
||||
private boolean allowInvalidSsl;
|
||||
|
||||
public HttpClient() { this(false); }
|
||||
public HttpClient(boolean allowInvalidSsl) { this.allowInvalidSsl = allowInvalidSsl; }
|
||||
|
||||
public Optional<Response> get(Request r) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
return process("GET", r, "");
|
||||
}
|
||||
|
||||
public Optional<Response> post(Request r, String body) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
if (!r.getCustomHeaders().containsKey("content-length")) {
|
||||
r.getCustomHeaders().put("content-length", String.valueOf(body.length()));
|
||||
}
|
||||
return process("POST", r, body);
|
||||
}
|
||||
|
||||
public Optional<Response> put(Request r, String body) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
if (!r.getCustomHeaders().containsKey("content-length")) {
|
||||
r.getCustomHeaders().put("content-length", String.valueOf(body.length()));
|
||||
}
|
||||
return process("PUT", r, body);
|
||||
}
|
||||
|
||||
public Optional<Response> delete(Request r) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
return process("DELETE", r, "");
|
||||
}
|
||||
|
||||
public Optional<Response> head(Request r) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
return process("HEAD", r, "");
|
||||
}
|
||||
|
||||
private Optional<Response> process(String method, Request r, String body) throws IOException, NoSuchAlgorithmException, KeyManagementException {
|
||||
String headers = buildHeaders(method, r);
|
||||
Socket s = (r.getScheme().equals("https")) ?
|
||||
buildSSLSocket(resolve(r.getHost()).getHostAddress(), r.getPort())
|
||||
: buildSocket(resolve(r.getHost()).getHostAddress(), r.getPort());
|
||||
String request = (method.equals("POST") || method.equals("PUT")) ?
|
||||
new StringBuilder(headers).append(body).toString() : headers;
|
||||
if (s.isConnected()) {
|
||||
Instant start = Instant.now();
|
||||
try {
|
||||
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
|
||||
bos.write(request.getBytes(StandardCharsets.UTF_8));
|
||||
bos.flush();
|
||||
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
|
||||
byte[] b = bis.readAllBytes();
|
||||
Instant end = Instant.now();
|
||||
long time = end.toEpochMilli() - start.toEpochMilli();
|
||||
r.setRawRequest(request);
|
||||
return Optional.of(new Response(b, time, r));
|
||||
} finally {
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private InetAddress resolve(String host) throws UnknownHostException {
|
||||
InetAddress[] addresses = InetAddress.getAllByName(host);
|
||||
return addresses[0];
|
||||
}
|
||||
|
||||
private Socket buildSocket(String host, int port) throws IOException {
|
||||
Socket s = new Socket(host, port);
|
||||
s.setKeepAlive(false);
|
||||
s.setSoTimeout(DEFAULT_TIMEOUT);
|
||||
return s;
|
||||
}
|
||||
|
||||
private Socket buildSSLSocket(String host, int port) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||
SSLSocketFactory factory;
|
||||
if(!allowInvalidSsl) {
|
||||
factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
|
||||
} else {
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{
|
||||
new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}
|
||||
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType){}
|
||||
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType){}
|
||||
}
|
||||
};
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
factory = sc.getSocketFactory();
|
||||
}
|
||||
Socket s = factory.createSocket(host, port);
|
||||
((SSLSocket)s).setEnabledProtocols(new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" });
|
||||
s.setKeepAlive(false);
|
||||
s.setSoTimeout(DEFAULT_TIMEOUT);
|
||||
((SSLSocket)s).startHandshake();
|
||||
return s;
|
||||
}
|
||||
|
||||
private String buildHeaders(String method, Request r) {
|
||||
Map<String, String> custom = r.getCustomHeaders();
|
||||
String path = (r.getParams().isEmpty()) ?
|
||||
r.getPath() : r.getPathWithParams();
|
||||
final StringBuilder sb = new StringBuilder(method).append(" ").append(path)
|
||||
.append(" HTTP/1.1").append(CRLF);
|
||||
sb.append("host: ").append(r.getHost()).append(":").append(r.getPort()).append(CRLF);
|
||||
sb.append("connection: close").append(CRLF);
|
||||
if (!custom.containsKey("accept")) {
|
||||
sb.append("accept: */*").append(CRLF);
|
||||
}
|
||||
if (!custom.containsKey("user-agent")) {
|
||||
sb.append("user-agent: endpoint/1.0").append(CRLF);
|
||||
}
|
||||
for (Map.Entry<String, String> h : custom.entrySet()) {
|
||||
sb.append(h.getKey()).append(": ").append(h.getValue()).append(CRLF);
|
||||
}
|
||||
return sb.append(CRLF).toString();
|
||||
}
|
||||
|
||||
}
|
||||
102
src/ovh/alexisdelhaie/endpoint/http/Request.java
Normal file
102
src/ovh/alexisdelhaie/endpoint/http/Request.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import ovh.alexisdelhaie.endpoint.URLGenerator;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Request {
|
||||
|
||||
private String host;
|
||||
private String scheme;
|
||||
private String path;
|
||||
private int port;
|
||||
private HashMap<String, String> params;
|
||||
private HashMap<String, String> customHeaders;
|
||||
private String body;
|
||||
private String rawRequest;
|
||||
|
||||
Request(String host, String scheme, String path, int port,
|
||||
HashMap<String, String> params, HashMap<String, String> customHeaders, String body) {
|
||||
this.host = host;
|
||||
this.scheme = scheme;
|
||||
this.path = path;
|
||||
this.port = port;
|
||||
this.params = params;
|
||||
this.customHeaders = customHeaders;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public String getScheme() {
|
||||
return scheme;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getPathWithParams() {
|
||||
return String.format("%s%s", path, URLGenerator.generateParamsPartWithEncoding(params));
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getCustomHeaders() {
|
||||
return customHeaders;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public String getRawRequest() {
|
||||
return rawRequest;
|
||||
}
|
||||
|
||||
void setRawRequest(String r) {
|
||||
rawRequest = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Request request = (Request) o;
|
||||
return getPort() == request.getPort() &&
|
||||
Objects.equals(getHost(), request.getHost()) &&
|
||||
Objects.equals(getScheme(), request.getScheme()) &&
|
||||
Objects.equals(getPath(), request.getPath()) &&
|
||||
Objects.equals(getParams(), request.getParams()) &&
|
||||
Objects.equals(getCustomHeaders(), request.getCustomHeaders()) &&
|
||||
Objects.equals(getBody(), request.getBody());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getHost(), getScheme(), getPath(), getPort(), getParams(), getCustomHeaders(), getBody());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("Request{");
|
||||
sb.append("scheme='").append(scheme).append('\'');
|
||||
sb.append(", host='").append(host).append('\'');
|
||||
sb.append(", port=").append(port);
|
||||
sb.append(", path='").append(path).append('\'');
|
||||
sb.append(", params=").append(params);
|
||||
sb.append(", customHeaders=").append(customHeaders);
|
||||
sb.append(", body='").append(body).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
94
src/ovh/alexisdelhaie/endpoint/http/RequestBuilder.java
Normal file
94
src/ovh/alexisdelhaie/endpoint/http/RequestBuilder.java
Normal file
@@ -0,0 +1,94 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class RequestBuilder {
|
||||
|
||||
public static int HTTP_PORT = 80;
|
||||
public static int HTTPS_PORT = 443;
|
||||
public static String HTTP_SCHEME = "http";
|
||||
public static String HTTPS_SCHEME = "https";
|
||||
|
||||
private String host;
|
||||
private String scheme;
|
||||
private String path;
|
||||
private int port;
|
||||
private HashMap<String, String> params;
|
||||
private HashMap<String, String> customHeaders;
|
||||
private String body;
|
||||
|
||||
public RequestBuilder (String url) throws MalformedURLException {
|
||||
params = new HashMap<>();
|
||||
customHeaders = new HashMap<>();
|
||||
scheme = (url.toLowerCase().startsWith("https://")) ? HTTPS_SCHEME : HTTP_SCHEME;
|
||||
url = (!url.toLowerCase().startsWith("https://")
|
||||
&& !url.toLowerCase().startsWith("http://")) ? "http://" + url : url;
|
||||
URL u = new URL(url);
|
||||
host = u.getHost();
|
||||
path = (u.getPath().isBlank()) ? "/" : u.getPath();
|
||||
port = u.getPort();
|
||||
if (port == -1) {
|
||||
port = (scheme.equals(HTTPS_SCHEME)) ? HTTPS_PORT : HTTP_PORT;
|
||||
}
|
||||
parseParams(url);
|
||||
}
|
||||
|
||||
private void parseParams(String url) {
|
||||
String[] p = url.split("[?]");
|
||||
if (p.length == 2) {
|
||||
String[] couples = p[1].split("[&]");
|
||||
for (String c: couples) {
|
||||
String[] v = c.split("[=]");
|
||||
if (v.length == 2) {
|
||||
params.put(v[0], v[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RequestBuilder setHost(String host) {
|
||||
this.host = host;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setScheme(String scheme) {
|
||||
this.scheme = scheme;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setPort(int port) {
|
||||
this.port = port;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setBody(String body) {
|
||||
this.body = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setPath(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setCustomHeaders(HashMap<String, String> custom) {
|
||||
this.customHeaders.clear();
|
||||
for (Map.Entry<String, String> entry : custom.entrySet()) {
|
||||
this.customHeaders.put(entry.getKey().toLowerCase(), entry.getValue());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder addCustomHeader(String key, String value) {
|
||||
this.customHeaders.put(key.toLowerCase(), value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Request build() {
|
||||
return new Request(host, scheme, path, port, params, customHeaders, body);
|
||||
}
|
||||
|
||||
}
|
||||
130
src/ovh/alexisdelhaie/endpoint/http/Response.java
Normal file
130
src/ovh/alexisdelhaie/endpoint/http/Response.java
Normal file
@@ -0,0 +1,130 @@
|
||||
package ovh.alexisdelhaie.endpoint.http;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Response {
|
||||
|
||||
public final static String CRLF = "\r\n";
|
||||
public final static String DOUBLE_CRLF = "\r\n\r\n";
|
||||
|
||||
private HashMap<String, String> headers;
|
||||
private String rawHeaders;
|
||||
private String rawResponse;
|
||||
private String body;
|
||||
private int statusCode;
|
||||
private String status;
|
||||
private long time;
|
||||
private Request request;
|
||||
|
||||
Response(byte[] res, long time, Request r) throws UnsupportedEncodingException {
|
||||
headers = new HashMap<>();
|
||||
rawResponse = new String(res, StandardCharsets.UTF_8);
|
||||
int crlf = rawResponse.indexOf(DOUBLE_CRLF);
|
||||
String h = rawResponse.substring(0, crlf);
|
||||
rawHeaders = h;
|
||||
parseHeaders();
|
||||
rawResponse = new String(res, getEncoding());
|
||||
body = rawResponse.substring(crlf + DOUBLE_CRLF.length());
|
||||
this.time = time;
|
||||
request = r;
|
||||
}
|
||||
|
||||
private void parseHeaders() {
|
||||
String[] hh = rawHeaders.split(CRLF);
|
||||
parseStatus(hh[0]);
|
||||
for (String c : hh) {
|
||||
String[] entry = c.split(":\\s");
|
||||
if (entry.length == 2) {
|
||||
headers.put(entry[0].toLowerCase(), entry[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseStatus(String l) {
|
||||
Pattern p = Pattern.compile("(HTTP/1.1)\\s([0-9]{3})\\s(.+)");
|
||||
Matcher m = p.matcher(l);
|
||||
if (m.matches()) {
|
||||
statusCode = Integer.parseInt(m.group(2));
|
||||
status = m.group(3);
|
||||
}
|
||||
}
|
||||
|
||||
private String getEncoding() {
|
||||
Pattern p = Pattern.compile("(.+);\\s(.+)=(.+)");
|
||||
if (headers.containsKey("content-type")) {
|
||||
String value = headers.get("content-type");
|
||||
Matcher m = p.matcher(value);
|
||||
if (m.matches()) {
|
||||
return m.group(3);
|
||||
}
|
||||
}
|
||||
return StandardCharsets.UTF_8.toString();
|
||||
}
|
||||
|
||||
public HashMap<String, String> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public String getRawHeaders() {
|
||||
return rawHeaders;
|
||||
}
|
||||
|
||||
public String getRawResponse() {
|
||||
return rawResponse;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public Request getRequest() { return request; }
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Response)) return false;
|
||||
Response response = (Response) o;
|
||||
return statusCode == response.statusCode &&
|
||||
time == response.time &&
|
||||
headers.equals(response.headers) &&
|
||||
rawHeaders.equals(response.rawHeaders) &&
|
||||
rawResponse.equals(response.rawResponse) &&
|
||||
body.equals(response.body) &&
|
||||
status.equals(response.status) &&
|
||||
request.equals(response.request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(headers, rawHeaders, rawResponse, body, statusCode, status, time, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("Response{");
|
||||
sb.append("headers=").append(headers);
|
||||
sb.append(", body='").append(body).append('\'');
|
||||
sb.append(", statusCode=").append(statusCode);
|
||||
sb.append(", status='").append(status).append('\'');
|
||||
sb.append(", time=").append(time);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
BIN
src/ovh/alexisdelhaie/endpoint/icon.png
Normal file
BIN
src/ovh/alexisdelhaie/endpoint/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
135
src/ovh/alexisdelhaie/endpoint/impl/EditCell.java
Normal file
135
src/ovh/alexisdelhaie/endpoint/impl/EditCell.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
Stolen code from Github : https://gist.github.com/james-d/be5bbd6255a4640a5357#file-editcell-java-L109
|
||||
*/
|
||||
package ovh.alexisdelhaie.endpoint.impl;
|
||||
|
||||
import javafx.event.Event;
|
||||
import javafx.scene.control.ContentDisplay;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableColumn.CellEditEvent;
|
||||
import javafx.scene.control.TablePosition;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
|
||||
public class EditCell<S, T> extends TableCell<S, T> {
|
||||
|
||||
// Text field for editing
|
||||
// TODO: allow this to be a plugable control.
|
||||
private final TextField textField = new TextField();
|
||||
|
||||
// Converter for converting the text in the text field to the user type, and vice-versa:
|
||||
private final StringConverter<T> converter ;
|
||||
|
||||
public EditCell(StringConverter<T> converter) {
|
||||
this.converter = converter ;
|
||||
|
||||
itemProperty().addListener((obx, oldItem, newItem) -> {
|
||||
if (newItem == null) {
|
||||
setText(null);
|
||||
} else {
|
||||
setText(converter.toString(newItem));
|
||||
}
|
||||
});
|
||||
setGraphic(textField);
|
||||
setContentDisplay(ContentDisplay.TEXT_ONLY);
|
||||
|
||||
textField.setOnAction(evt -> {
|
||||
commitEdit(this.converter.fromString(textField.getText()));
|
||||
});
|
||||
textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
|
||||
if (! isNowFocused) {
|
||||
commitEdit(this.converter.fromString(textField.getText()));
|
||||
}
|
||||
});
|
||||
textField.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||
if (event.getCode() == KeyCode.ESCAPE) {
|
||||
textField.setText(converter.toString(getItem()));
|
||||
cancelEdit();
|
||||
event.consume();
|
||||
} else if (event.getCode() == KeyCode.RIGHT) {
|
||||
getTableView().getSelectionModel().selectRightCell();
|
||||
event.consume();
|
||||
} else if (event.getCode() == KeyCode.LEFT) {
|
||||
getTableView().getSelectionModel().selectLeftCell();
|
||||
event.consume();
|
||||
} else if (event.getCode() == KeyCode.UP) {
|
||||
getTableView().getSelectionModel().selectAboveCell();
|
||||
event.consume();
|
||||
} else if (event.getCode() == KeyCode.DOWN) {
|
||||
getTableView().getSelectionModel().selectBelowCell();
|
||||
event.consume();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience converter that does nothing (converts Strings to themselves and vice-versa...).
|
||||
*/
|
||||
public static final StringConverter<String> IDENTITY_CONVERTER = new StringConverter<String>() {
|
||||
|
||||
@Override
|
||||
public String toString(String object) {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fromString(String string) {
|
||||
return string;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience method for creating an EditCell for a String value.
|
||||
* @return
|
||||
*/
|
||||
public static <S> EditCell<S, String> createStringEditCell() {
|
||||
return new EditCell<S, String>(IDENTITY_CONVERTER);
|
||||
}
|
||||
|
||||
|
||||
// set the text of the text field and display the graphic
|
||||
@Override
|
||||
public void startEdit() {
|
||||
super.startEdit();
|
||||
textField.setText(converter.toString(getItem()));
|
||||
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
|
||||
textField.requestFocus();
|
||||
}
|
||||
|
||||
// revert to text display
|
||||
@Override
|
||||
public void cancelEdit() {
|
||||
super.cancelEdit();
|
||||
setContentDisplay(ContentDisplay.TEXT_ONLY);
|
||||
}
|
||||
|
||||
// commits the edit. Update property if possible and revert to text display
|
||||
@Override
|
||||
public void commitEdit(T item) {
|
||||
|
||||
// This block is necessary to support commit on losing focus, because the baked-in mechanism
|
||||
// sets our editing state to false before we can intercept the loss of focus.
|
||||
// The default commitEdit(...) method simply bails if we are not editing...
|
||||
if (! isEditing() && ! item.equals(getItem())) {
|
||||
TableView<S> table = getTableView();
|
||||
if (table != null) {
|
||||
TableColumn<S, T> column = getTableColumn();
|
||||
CellEditEvent<S, T> event = new CellEditEvent<>(table,
|
||||
new TablePosition<S,T>(table, getIndex(), column),
|
||||
TableColumn.editCommitEvent(), item);
|
||||
Event.fireEvent(column, event);
|
||||
}
|
||||
}
|
||||
|
||||
super.commitEdit(item);
|
||||
|
||||
setContentDisplay(ContentDisplay.TEXT_ONLY);
|
||||
}
|
||||
|
||||
}
|
||||
21
src/ovh/alexisdelhaie/endpoint/mainwindow.fxml
Normal file
21
src/ovh/alexisdelhaie/endpoint/mainwindow.fxml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ovh.alexisdelhaie.endpoint.Controller">
|
||||
<TextField fx:id="requestInput" layoutX="109.0" layoutY="39.0" onKeyTyped="#requestInputOnKeyPressed" prefHeight="25.0" prefWidth="861.0" AnchorPane.leftAnchor="109.0" AnchorPane.rightAnchor="96.99999999999989" AnchorPane.topAnchor="39.0" />
|
||||
<Button layoutX="979.0" layoutY="39.0" mnemonicParsing="false" onMouseClicked="#start" prefHeight="25.0" prefWidth="73.0" text="Send" AnchorPane.rightAnchor="16.0" AnchorPane.topAnchor="39.0" />
|
||||
<ChoiceBox id="httpMethod" fx:id="httpMethod" layoutX="14.0" layoutY="39.0" prefHeight="25.0" prefWidth="85.0" AnchorPane.leftAnchor="14.0" AnchorPane.topAnchor="39.0" />
|
||||
<Label layoutX="109.0" layoutY="21.0" text="Request URL" />
|
||||
<TabPane fx:id="tabs" layoutX="-1.0" layoutY="104.0" prefHeight="540.0" prefWidth="1067.0" tabClosingPolicy="ALL_TABS" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="104.0">
|
||||
</TabPane>
|
||||
<Button layoutX="1022.0" layoutY="71.0" mnemonicParsing="false" onMouseClicked="#createNewTab" prefHeight="25.0" prefWidth="31.0" text="+" AnchorPane.rightAnchor="16.0" AnchorPane.topAnchor="71.0" />
|
||||
<Button layoutX="1000.0" layoutY="71.0" mnemonicParsing="false" onMouseClicked="#showAboutDialog" prefHeight="25.0" prefWidth="31.0" text="?" AnchorPane.rightAnchor="58.0" AnchorPane.topAnchor="71.0" />
|
||||
<Pane fx:id="runningIndicatorPane" layoutX="109.0" layoutY="74.0" prefHeight="17.0" prefWidth="200.0" visible="false">
|
||||
<children>
|
||||
<ProgressIndicator layoutX="2.0" layoutY="1.0" prefHeight="17.0" prefWidth="18.0" />
|
||||
<Label layoutX="23.0" layoutY="1.0" prefHeight="17.0" prefWidth="133.0" text="Running..." />
|
||||
</children>
|
||||
</Pane>
|
||||
</AnchorPane>
|
||||
49
src/ovh/alexisdelhaie/endpoint/model/Param.java
Normal file
49
src/ovh/alexisdelhaie/endpoint/model/Param.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package ovh.alexisdelhaie.endpoint.model;
|
||||
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
|
||||
public class Param {
|
||||
|
||||
private final StringProperty _name = new SimpleStringProperty();
|
||||
private final StringProperty _value = new SimpleStringProperty();
|
||||
|
||||
public Param() {
|
||||
_name.set("");
|
||||
_value.set("");
|
||||
}
|
||||
|
||||
public Param(String n, String v) {
|
||||
_name.set(n);
|
||||
_value.set(v);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return _name.get();
|
||||
}
|
||||
|
||||
public StringProperty name() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return _value.get();
|
||||
}
|
||||
|
||||
public StringProperty value() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (_name.get().isBlank() && _value.get().isBlank());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("Param{");
|
||||
sb.append("_name=").append(_name.get());
|
||||
sb.append(", _value=").append(_value.get());
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
58
src/ovh/alexisdelhaie/endpoint/responsetab.fxml
Normal file
58
src/ovh/alexisdelhaie/endpoint/responsetab.fxml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="890.0" prefWidth="1149.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="295.0" minWidth="0.0" prefWidth="19.33333381017049" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="344.3333333333333" minWidth="10.0" prefWidth="55.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="648.6666781107585" minWidth="10.0" prefWidth="359.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="668.0" minWidth="5.333333333333314" prefWidth="17.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="678.0" minWidth="10.0" prefWidth="674.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="632.6666361490886" minWidth="10.0" prefWidth="23.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="128.00000762939453" minHeight="0.0" prefHeight="1.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="128.00000762939453" minHeight="0.0" prefHeight="16.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="201.0" minHeight="0.0" prefHeight="17.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="636.0" minHeight="10.0" prefHeight="461.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="188.0" minHeight="8.0" prefHeight="23.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="333.0" minHeight="10.0" prefHeight="326.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label text="Time" GridPane.columnIndex="1" GridPane.rowIndex="2" />
|
||||
<Label text="Status" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
<Label fx:id="status" text="..." GridPane.columnIndex="2" GridPane.rowIndex="1">
|
||||
<font>
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font></Label>
|
||||
<Label fx:id="time" text="... ms" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<font>
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font></Label>
|
||||
<TableView fx:id="headers" prefHeight="321.0" prefWidth="599.0" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="3">
|
||||
<columns>
|
||||
<TableColumn prefWidth="75.0" text="Key" />
|
||||
<TableColumn prefWidth="75.0" text="Value" />
|
||||
</columns>
|
||||
<columnResizePolicy>
|
||||
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
|
||||
</columnResizePolicy>
|
||||
</TableView>
|
||||
<TextArea fx:id="raw" editable="false" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="4" GridPane.rowIndex="3">
|
||||
<font>
|
||||
<Font name="Consolas" size="12.0" />
|
||||
</font>
|
||||
</TextArea>
|
||||
<Label text="Raw" GridPane.columnIndex="4" GridPane.rowIndex="2" />
|
||||
<TextArea fx:id="request" editable="false" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="4" GridPane.rowIndex="5">
|
||||
<font>
|
||||
<Font name="Consolas" size="12.0" />
|
||||
</font>
|
||||
</TextArea>
|
||||
<Label text="Sended request" GridPane.columnIndex="4" GridPane.rowIndex="4" />
|
||||
</children>
|
||||
</GridPane>
|
||||
Reference in New Issue
Block a user