Code refactor, adding GoLand workspace with Bazel plugin.
This commit is contained in:
		
							
								
								
									
										18
									
								
								.ijwb/.bazelproject
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								.ijwb/.bazelproject
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
directories:
 | 
			
		||||
  .
 | 
			
		||||
 | 
			
		||||
# Automatically includes all relevant targets under the 'directories' above
 | 
			
		||||
derive_targets_from_directories: true
 | 
			
		||||
 | 
			
		||||
targets:
 | 
			
		||||
  # If source code isn't resolving, add additional targets that compile it here
 | 
			
		||||
 | 
			
		||||
additional_languages:
 | 
			
		||||
  # Uncomment any additional languages you want supported
 | 
			
		||||
  # dart
 | 
			
		||||
  # javascript
 | 
			
		||||
  # python
 | 
			
		||||
  # typescript
 | 
			
		||||
 | 
			
		||||
build_flags:
 | 
			
		||||
  --features=pure
 | 
			
		||||
							
								
								
									
										11
									
								
								.ijwb/.blaze/modules/.project-data-dir.iml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.ijwb/.blaze/modules/.project-data-dir.iml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<module external.system.id="Blaze" type="WEB_MODULE" version="4">
 | 
			
		||||
  <component name="NewModuleRootManager">
 | 
			
		||||
    <content url="file://$MODULE_DIR$/../..">
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/.." />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/../../.idea" />
 | 
			
		||||
    </content>
 | 
			
		||||
    <orderEntry type="inheritedJdk" />
 | 
			
		||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
			
		||||
  </component>
 | 
			
		||||
</module>
 | 
			
		||||
							
								
								
									
										17
									
								
								.ijwb/.blaze/modules/.workspace.iml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.ijwb/.blaze/modules/.workspace.iml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<module external.system.id="Blaze" type="WEB_MODULE" version="4">
 | 
			
		||||
  <component name="Go" enabled="true" />
 | 
			
		||||
  <component name="NewModuleRootManager">
 | 
			
		||||
    <content url="file://$MODULE_DIR$/../../..">
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/../../.." isTestSource="false" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/../.." />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/../../../bazel-bin" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/../../../bazel-genfiles" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/../../../bazel-navigator" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/../../../bazel-out" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/../../../bazel-testlogs" />
 | 
			
		||||
    </content>
 | 
			
		||||
    <orderEntry type="inheritedJdk" />
 | 
			
		||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
			
		||||
  </component>
 | 
			
		||||
</module>
 | 
			
		||||
							
								
								
									
										6
									
								
								.ijwb/.idea/$CACHE_FILE$
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.ijwb/.idea/$CACHE_FILE$
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="NodePackageJsonFileManager">
 | 
			
		||||
    <packageJsonPaths />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										6
									
								
								.ijwb/.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.ijwb/.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
# Default ignored files
 | 
			
		||||
/workspace.xml
 | 
			
		||||
# Project exclude paths
 | 
			
		||||
/.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								.ijwb/.idea/.name
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.ijwb/.idea/.name
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
navigator
 | 
			
		||||
							
								
								
									
										3
									
								
								.ijwb/.idea/dictionaries/eve.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.ijwb/.idea/dictionaries/eve.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
<component name="ProjectDictionaryState">
 | 
			
		||||
  <dictionary name="eve" />
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										6
									
								
								.ijwb/.idea/externalDependencies.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.ijwb/.idea/externalDependencies.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="ExternalDependencies">
 | 
			
		||||
    <plugin id="com.google.idea.bazel.ijwb" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										72
									
								
								.ijwb/.idea/misc.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								.ijwb/.idea/misc.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="MarkdownProjectSettings">
 | 
			
		||||
    <PreviewSettings splitEditorLayout="SPLIT" splitEditorPreview="PREVIEW" useGrayscaleRendering="false" zoomFactor="1.0" maxImageWidth="0" showGitHubPageIfSynced="false" allowBrowsingInPreview="false" synchronizePreviewPosition="true" highlightPreviewType="NONE" highlightFadeOut="5" highlightOnTyping="true" synchronizeSourcePosition="true" verticallyAlignSourceAndPreviewSyncPosition="true" showSearchHighlightsInPreview="false" showSelectionInPreview="true" openRemoteLinks="true">
 | 
			
		||||
      <PanelProvider>
 | 
			
		||||
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.panel" providerName="Default - Swing" />
 | 
			
		||||
      </PanelProvider>
 | 
			
		||||
    </PreviewSettings>
 | 
			
		||||
    <ParserSettings gitHubSyntaxChange="false">
 | 
			
		||||
      <PegdownExtensions>
 | 
			
		||||
        <option name="ABBREVIATIONS" value="false" />
 | 
			
		||||
        <option name="ANCHORLINKS" value="true" />
 | 
			
		||||
        <option name="ASIDE" value="false" />
 | 
			
		||||
        <option name="ATXHEADERSPACE" value="true" />
 | 
			
		||||
        <option name="AUTOLINKS" value="true" />
 | 
			
		||||
        <option name="DEFINITIONS" value="false" />
 | 
			
		||||
        <option name="DEFINITION_BREAK_DOUBLE_BLANK_LINE" value="false" />
 | 
			
		||||
        <option name="FENCED_CODE_BLOCKS" value="true" />
 | 
			
		||||
        <option name="FOOTNOTES" value="false" />
 | 
			
		||||
        <option name="HARDWRAPS" value="false" />
 | 
			
		||||
        <option name="HTML_DEEP_PARSER" value="false" />
 | 
			
		||||
        <option name="INSERTED" value="false" />
 | 
			
		||||
        <option name="QUOTES" value="false" />
 | 
			
		||||
        <option name="RELAXEDHRULES" value="true" />
 | 
			
		||||
        <option name="SMARTS" value="false" />
 | 
			
		||||
        <option name="STRIKETHROUGH" value="true" />
 | 
			
		||||
        <option name="SUBSCRIPT" value="false" />
 | 
			
		||||
        <option name="SUPERSCRIPT" value="false" />
 | 
			
		||||
        <option name="SUPPRESS_HTML_BLOCKS" value="false" />
 | 
			
		||||
        <option name="SUPPRESS_INLINE_HTML" value="false" />
 | 
			
		||||
        <option name="TABLES" value="true" />
 | 
			
		||||
        <option name="TASKLISTITEMS" value="true" />
 | 
			
		||||
        <option name="TOC" value="false" />
 | 
			
		||||
        <option name="WIKILINKS" value="true" />
 | 
			
		||||
      </PegdownExtensions>
 | 
			
		||||
      <ParserOptions>
 | 
			
		||||
        <option name="COMMONMARK_LISTS" value="true" />
 | 
			
		||||
        <option name="DUMMY" value="false" />
 | 
			
		||||
        <option name="EMOJI_SHORTCUTS" value="true" />
 | 
			
		||||
        <option name="FLEXMARK_FRONT_MATTER" value="false" />
 | 
			
		||||
        <option name="GFM_LOOSE_BLANK_LINE_AFTER_ITEM_PARA" value="false" />
 | 
			
		||||
        <option name="GFM_TABLE_RENDERING" value="true" />
 | 
			
		||||
        <option name="GITBOOK_URL_ENCODING" value="false" />
 | 
			
		||||
        <option name="GITHUB_EMOJI_URL" value="false" />
 | 
			
		||||
        <option name="GITHUB_LISTS" value="false" />
 | 
			
		||||
        <option name="GITHUB_WIKI_LINKS" value="true" />
 | 
			
		||||
        <option name="JEKYLL_FRONT_MATTER" value="false" />
 | 
			
		||||
        <option name="SIM_TOC_BLANK_LINE_SPACER" value="true" />
 | 
			
		||||
      </ParserOptions>
 | 
			
		||||
    </ParserSettings>
 | 
			
		||||
    <HtmlSettings headerTopEnabled="false" headerBottomEnabled="false" bodyTopEnabled="false" bodyBottomEnabled="false" embedUrlContent="false" addPageHeader="true" embedImages="false" embedHttpImages="false">
 | 
			
		||||
      <GeneratorProvider>
 | 
			
		||||
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.generator" providerName="Default Swing HTML Generator" />
 | 
			
		||||
      </GeneratorProvider>
 | 
			
		||||
      <headerTop />
 | 
			
		||||
      <headerBottom />
 | 
			
		||||
      <bodyTop />
 | 
			
		||||
      <bodyBottom />
 | 
			
		||||
    </HtmlSettings>
 | 
			
		||||
    <CssSettings previewScheme="UI_SCHEME" cssUri="" isCssUriEnabled="false" isCssTextEnabled="false" isDynamicPageWidth="true">
 | 
			
		||||
      <StylesheetProvider>
 | 
			
		||||
        <provider providerId="com.vladsch.idea.multimarkdown.editor.swing.html.css" providerName="Default Swing Stylesheet" />
 | 
			
		||||
      </StylesheetProvider>
 | 
			
		||||
      <ScriptProviders />
 | 
			
		||||
      <cssText />
 | 
			
		||||
    </CssSettings>
 | 
			
		||||
    <HtmlExportSettings updateOnSave="false" parentDir="$ProjectFileDir$" targetDir="$ProjectFileDir$" cssDir="" scriptDir="" plainHtml="false" imageDir="" copyLinkedImages="false" imageUniquifyType="0" targetExt="" useTargetExt="false" noCssNoScripts="false" linkToExportedHtml="true" exportOnSettingsChange="true" regenerateOnProjectOpen="false" linkFormatType="HTTP_ABSOLUTE" />
 | 
			
		||||
    <LinkMapSettings>
 | 
			
		||||
      <textMaps />
 | 
			
		||||
    </LinkMapSettings>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										9
									
								
								.ijwb/.idea/modules.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.ijwb/.idea/modules.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="ProjectModuleManager">
 | 
			
		||||
    <modules>
 | 
			
		||||
      <module fileurl="file://$PROJECT_DIR$/.blaze/modules/.project-data-dir.iml" filepath="$PROJECT_DIR$/.blaze/modules/.project-data-dir.iml" />
 | 
			
		||||
      <module fileurl="file://$PROJECT_DIR$/.blaze/modules/.workspace.iml" filepath="$PROJECT_DIR$/.blaze/modules/.workspace.iml" />
 | 
			
		||||
    </modules>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										18
									
								
								.ijwb/.idea/runConfigurations.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								.ijwb/.idea/runConfigurations.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="RunConfigurationProducerService">
 | 
			
		||||
    <option name="ignoredProducers">
 | 
			
		||||
      <set>
 | 
			
		||||
        <option value="com.goide.execution.application.GoApplicationRunConfigurationProducer" />
 | 
			
		||||
        <option value="com.goide.execution.testing.frameworks.gobench.GobenchRunConfigurationProducer" />
 | 
			
		||||
        <option value="com.goide.execution.testing.frameworks.gocheck.GocheckRunConfigurationProducer" />
 | 
			
		||||
        <option value="com.goide.execution.testing.frameworks.gotest.GotestRunConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.javascript.jest.JestRunConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.javascript.protractor.ProtractorRunConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.lang.javascript.buildTools.grunt.rc.GruntRunConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.lang.javascript.buildTools.gulp.rc.GulpRunConfigurationProducer" />
 | 
			
		||||
        <option value="com.intellij.lang.javascript.buildTools.npm.rc.NpmRunConfigurationProducer" />
 | 
			
		||||
      </set>
 | 
			
		||||
    </option>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										6
									
								
								.ijwb/.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.ijwb/.idea/vcs.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="VcsDirectoryMappings">
 | 
			
		||||
    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										49
									
								
								.ijwb/.idea/watcherTasks.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								.ijwb/.idea/watcherTasks.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="ProjectTasksOptions">
 | 
			
		||||
    <TaskOptions isEnabled="true">
 | 
			
		||||
      <option name="arguments" value="fmt $FilePath$" />
 | 
			
		||||
      <option name="checkSyntaxErrors" value="true" />
 | 
			
		||||
      <option name="description" />
 | 
			
		||||
      <option name="exitCodeBehavior" value="ERROR" />
 | 
			
		||||
      <option name="fileExtension" value="go" />
 | 
			
		||||
      <option name="immediateSync" value="true" />
 | 
			
		||||
      <option name="name" value="go fmt" />
 | 
			
		||||
      <option name="output" value="$FilePath$" />
 | 
			
		||||
      <option name="outputFilters">
 | 
			
		||||
        <array />
 | 
			
		||||
      </option>
 | 
			
		||||
      <option name="outputFromStdout" value="false" />
 | 
			
		||||
      <option name="program" value="$GoExecPath$" />
 | 
			
		||||
      <option name="runOnExternalChanges" value="false" />
 | 
			
		||||
      <option name="scopeName" value="Project Files" />
 | 
			
		||||
      <option name="trackOnlyRoot" value="true" />
 | 
			
		||||
      <option name="workingDir" value="$ProjectFileDir$" />
 | 
			
		||||
      <envs>
 | 
			
		||||
        <env name="GOROOT" value="$GOROOT$" />
 | 
			
		||||
        <env name="GOPATH" value="$GOPATH$" />
 | 
			
		||||
        <env name="PATH" value="$GoBinDirs$" />
 | 
			
		||||
      </envs>
 | 
			
		||||
    </TaskOptions>
 | 
			
		||||
    <TaskOptions isEnabled="true">
 | 
			
		||||
      <option name="arguments" value="run //:gazelle -- -go_prefix git.eve.moe/jackyyf/navigator" />
 | 
			
		||||
      <option name="checkSyntaxErrors" value="true" />
 | 
			
		||||
      <option name="description" />
 | 
			
		||||
      <option name="exitCodeBehavior" value="ERROR" />
 | 
			
		||||
      <option name="fileExtension" value="go" />
 | 
			
		||||
      <option name="immediateSync" value="true" />
 | 
			
		||||
      <option name="name" value="gazelle" />
 | 
			
		||||
      <option name="output" value="" />
 | 
			
		||||
      <option name="outputFilters">
 | 
			
		||||
        <array />
 | 
			
		||||
      </option>
 | 
			
		||||
      <option name="outputFromStdout" value="false" />
 | 
			
		||||
      <option name="program" value="bazel" />
 | 
			
		||||
      <option name="runOnExternalChanges" value="true" />
 | 
			
		||||
      <option name="scopeName" value="All Places" />
 | 
			
		||||
      <option name="trackOnlyRoot" value="false" />
 | 
			
		||||
      <option name="workingDir" value="$Projectpath$" />
 | 
			
		||||
      <envs />
 | 
			
		||||
    </TaskOptions>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
@ -10,15 +10,16 @@ go_library(
 | 
			
		||||
    importpath = "git.eve.moe/jackyyf/navigator",
 | 
			
		||||
    visibility = ["//visibility:private"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//api/beacon/v1:go_default_library",
 | 
			
		||||
        "//api/navigator:go_default_library",
 | 
			
		||||
        "//ipgeo:go_default_library",
 | 
			
		||||
        "//mapping:go_default_library",
 | 
			
		||||
        "@com_github_ipipdotnet_ipdb_go//:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_binary(
 | 
			
		||||
    name = "navigator",
 | 
			
		||||
	pure = "on",
 | 
			
		||||
    data = glob(["rules/**"]),
 | 
			
		||||
    embed = [":go_default_library"],
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								api/beacon/BUILD.bazel
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								api/beacon/BUILD.bazel
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = ["api.go"],
 | 
			
		||||
    importpath = "git.eve.moe/jackyyf/navigator/api/beacon",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										18
									
								
								api/beacon/api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								api/beacon/api.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
package beacon
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	apiServeMux = http.NewServeMux()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	http.Handle("/beacon/", http.StripPrefix("/beacon", apiServeMux))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RegisterApi(version string, handler http.Handler) {
 | 
			
		||||
	apiServeMux.Handle(fmt.Sprintf("/%s/", version), http.StripPrefix(fmt.Sprint("/", version), handler))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								api/beacon/v1/BUILD.bazel
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								api/beacon/v1/BUILD.bazel
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = ["api.go"],
 | 
			
		||||
    importpath = "git.eve.moe/jackyyf/navigator/api/beacon/v1",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//api/beacon:go_default_library",
 | 
			
		||||
        "//mapping:go_default_library",
 | 
			
		||||
        "//utils:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										33
									
								
								api/beacon/v1/api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								api/beacon/v1/api.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
			
		||||
package v1
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"git.eve.moe/jackyyf/navigator/api/beacon"
 | 
			
		||||
	"git.eve.moe/jackyyf/navigator/mapping"
 | 
			
		||||
	"git.eve.moe/jackyyf/navigator/utils"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	serveMux = http.NewServeMux()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	serveMux.HandleFunc("/getNodes", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		host := utils.GetRemoteIP(req)
 | 
			
		||||
		nodes := mapping.GetNodes()
 | 
			
		||||
		if nodes == nil {
 | 
			
		||||
			utils.ResponseWithJsonError(resp, http.StatusInternalServerError, "Unable to get nodes")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		suffix := mapping.GetSuffix(host)
 | 
			
		||||
		resp.Header().Set("Content-Type", "application/json")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		jsonEncoder := json.NewEncoder(resp)
 | 
			
		||||
		jsonEncoder.Encode(map[string]interface{}{
 | 
			
		||||
			"nodes":  nodes,
 | 
			
		||||
			"suffix": suffix,
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
	beacon.RegisterApi("v1", serveMux)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								api/navigator/BUILD.bazel
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								api/navigator/BUILD.bazel
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = ["api.go"],
 | 
			
		||||
    importpath = "git.eve.moe/jackyyf/navigator/api/navigator",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//ipgeo:go_default_library",
 | 
			
		||||
        "//mapping:go_default_library",
 | 
			
		||||
        "//utils:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										109
									
								
								api/navigator/api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								api/navigator/api.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
			
		||||
package navigator
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"git.eve.moe/jackyyf/navigator/ipgeo"
 | 
			
		||||
	"git.eve.moe/jackyyf/navigator/mapping"
 | 
			
		||||
	"git.eve.moe/jackyyf/navigator/utils"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	errIPv4Only = "Navigator works for valid IPv4 only :)"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	http.HandleFunc("/healthz", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		resp.WriteHeader(200)
 | 
			
		||||
		resp.Write([]byte("ok"))
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/info", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		var host string
 | 
			
		||||
		if argIp := req.FormValue("ip"); argIp != "" {
 | 
			
		||||
			host = argIp
 | 
			
		||||
			if net.ParseIP(host).To4() == nil {
 | 
			
		||||
				utils.ResponseWithError(resp, http.StatusPreconditionFailed, errIPv4Only)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			host = utils.GetRemoteIP(req)
 | 
			
		||||
		}
 | 
			
		||||
		db := ipgeo.Get()
 | 
			
		||||
 | 
			
		||||
		info_cn, err := db.FindInfo(host, "CN")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(resp, "IP %s not found in the database.", host)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		info_en, err := db.FindInfo(host, "EN")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(resp, "IP %s not found in the database.", host)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		resp.Header().Set("Content-Type", "text/plain")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		server := mapping.Get(host)
 | 
			
		||||
		fmt.Fprintln(resp, "您的IP:", host)
 | 
			
		||||
		fmt.Fprintln(resp, "数据库中IP所属位置:", utils.BuildLocation(info_cn))
 | 
			
		||||
		if info_cn.IspDomain != "" {
 | 
			
		||||
			fmt.Fprintln(resp, "数据库中IP所属运营商:", info_cn.IspDomain)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintln(resp, "您被分配的CDN节点为:", server)
 | 
			
		||||
		fmt.Fprintln(resp)
 | 
			
		||||
		fmt.Fprintln(resp, strings.Repeat("=", 72))
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintln(resp, "Your IP:", host)
 | 
			
		||||
		fmt.Fprintln(resp, "Location for your IP according our database:", utils.BuildLocation(info_en))
 | 
			
		||||
		if info_en.IspDomain != "" {
 | 
			
		||||
			fmt.Fprintln(resp, "ISP for your IP according our database:", info_en.IspDomain)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintln(resp, "Allocated CDN node for you:", server)
 | 
			
		||||
		fmt.Fprintln(resp)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/mapping", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		host := utils.GetRemoteIP(req)
 | 
			
		||||
		resp.Header().Set("Content-Type", "text/plain")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		server := mapping.Get(host)
 | 
			
		||||
		fmt.Fprint(resp, server)
 | 
			
		||||
	})
 | 
			
		||||
	http.HandleFunc("/getMapping", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		ip := req.FormValue("ip")
 | 
			
		||||
		if net.ParseIP(ip).To4() == nil {
 | 
			
		||||
			utils.ResponseWithError(resp, http.StatusBadRequest, errIPv4Only)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		resp.Header().Set("Content-Type", "text/plain")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		server := mapping.Get(ip)
 | 
			
		||||
		log.Printf("%s => %s\n", ip, server)
 | 
			
		||||
		fmt.Fprint(resp, server)
 | 
			
		||||
	})
 | 
			
		||||
	http.HandleFunc("/getNodes", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		ip := req.FormValue("ip")
 | 
			
		||||
		if net.ParseIP(ip).To4() == nil {
 | 
			
		||||
			utils.ResponseWithError(resp, http.StatusBadRequest, errIPv4Only)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		nodes := mapping.GetNodes()
 | 
			
		||||
		if nodes == nil {
 | 
			
		||||
			utils.ResponseWithJsonError(resp, http.StatusInternalServerError, "Unable to get nodes")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		suffix := mapping.GetSuffix(ip)
 | 
			
		||||
		resp.Header().Set("Content-Type", "application/json")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		jsonEncoder := json.NewEncoder(resp)
 | 
			
		||||
		ret := make([]string, 0, len(nodes))
 | 
			
		||||
		for _, node := range nodes {
 | 
			
		||||
			ret = append(ret, node+suffix)
 | 
			
		||||
		}
 | 
			
		||||
		jsonEncoder.Encode(ret)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										183
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										183
									
								
								main.go
									
									
									
									
									
								
							@ -1,197 +1,24 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	_ "net/http/pprof"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	_ "git.eve.moe/jackyyf/navigator/api/beacon/v1"
 | 
			
		||||
	_ "git.eve.moe/jackyyf/navigator/api/navigator"
 | 
			
		||||
	"git.eve.moe/jackyyf/navigator/ipgeo"
 | 
			
		||||
	"git.eve.moe/jackyyf/navigator/mapping"
 | 
			
		||||
	"github.com/ipipdotnet/ipdb-go"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	_ "net/http/pprof"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	errIPv4Only      = "Navigator works for valid IPv4 only :)"
 | 
			
		||||
	remoteAddrHeader = "X-NAV-REMOTE-IP"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type errorMessage struct {
 | 
			
		||||
	Error string `json:error`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	listen_spec = flag.String("bind", "127.0.0.1:8086", "http server bind spec")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func responseWithError(resp http.ResponseWriter, statusCode int, message string) {
 | 
			
		||||
	resp.Header().Set("Content-Type", "text/plain")
 | 
			
		||||
	resp.WriteHeader(statusCode)
 | 
			
		||||
	resp.Write([]byte("error: " + message))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func responseWithJsonError(resp http.ResponseWriter, statusCode int, message string) {
 | 
			
		||||
	resp.Header().Set("Content-Type", "application/json")
 | 
			
		||||
	resp.WriteHeader(statusCode)
 | 
			
		||||
	encoder := json.NewEncoder(resp)
 | 
			
		||||
	err := encoder.Encode(&errorMessage{
 | 
			
		||||
		Error: message,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// This should never happen
 | 
			
		||||
		panic("json marshal failed, check code")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getRemoteIP(req *http.Request) string {
 | 
			
		||||
	if addr := req.Header.Get(remoteAddrHeader); addr != "" {
 | 
			
		||||
		if net.ParseIP(addr).To4() == nil {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
		return addr
 | 
			
		||||
	}
 | 
			
		||||
	host, _, err := net.SplitHostPort(req.RemoteAddr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	if net.ParseIP(host).To4() == nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	return host
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func buildLocation(info *ipdb.CityInfo) string {
 | 
			
		||||
	ret := ""
 | 
			
		||||
	if info.CountryName != "" {
 | 
			
		||||
		ret += info.CountryName + " "
 | 
			
		||||
	}
 | 
			
		||||
	if info.RegionName != "" {
 | 
			
		||||
		ret += info.RegionName + " "
 | 
			
		||||
	}
 | 
			
		||||
	if info.CityName != "" {
 | 
			
		||||
		ret += info.CityName + " "
 | 
			
		||||
	}
 | 
			
		||||
	return strings.TrimSpace(ret)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	flag.Parse()
 | 
			
		||||
	ipgeo.Initialize()
 | 
			
		||||
	mapping.Initialize()
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/healthz", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		resp.WriteHeader(200)
 | 
			
		||||
		resp.Write([]byte("ok"))
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/info", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		var host string
 | 
			
		||||
		if argIp := req.FormValue("ip"); argIp != "" {
 | 
			
		||||
			host = argIp
 | 
			
		||||
			if net.ParseIP(host).To4() == nil {
 | 
			
		||||
				responseWithError(resp, http.StatusPreconditionFailed, errIPv4Only)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			host = getRemoteIP(req)
 | 
			
		||||
		}
 | 
			
		||||
		db := ipgeo.Get()
 | 
			
		||||
 | 
			
		||||
		info_cn, err := db.FindInfo(host, "CN")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(resp, "IP %s not found in the database.", host)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		info_en, err := db.FindInfo(host, "EN")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(resp, "IP %s not found in the database.", host)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		resp.Header().Set("Content-Type", "text/plain")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		server := mapping.Get(host)
 | 
			
		||||
		fmt.Fprintln(resp, "您的IP:", host)
 | 
			
		||||
		fmt.Fprintln(resp, "数据库中IP所属位置:", buildLocation(info_cn))
 | 
			
		||||
		if info_cn.IspDomain != "" {
 | 
			
		||||
			fmt.Fprintln(resp, "数据库中IP所属运营商:", info_cn.IspDomain)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintln(resp, "您被分配的CDN节点为:", server)
 | 
			
		||||
		fmt.Fprintln(resp)
 | 
			
		||||
		fmt.Fprintln(resp, strings.Repeat("=", 72))
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintln(resp, "Your IP:", host)
 | 
			
		||||
		fmt.Fprintln(resp, "Location for your IP according our database:", buildLocation(info_en))
 | 
			
		||||
		if info_en.IspDomain != "" {
 | 
			
		||||
			fmt.Fprintln(resp, "ISP for your IP according our database:", info_en.IspDomain)
 | 
			
		||||
		}
 | 
			
		||||
		fmt.Fprintln(resp, "Allocated CDN node for you:", server)
 | 
			
		||||
		fmt.Fprintln(resp)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/mapping", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		host := getRemoteIP(req)
 | 
			
		||||
		resp.Header().Set("Content-Type", "text/plain")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		server := mapping.Get(host)
 | 
			
		||||
		fmt.Fprint(resp, server)
 | 
			
		||||
	})
 | 
			
		||||
	http.HandleFunc("/getMapping", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		ip := req.FormValue("ip")
 | 
			
		||||
		if net.ParseIP(ip).To4() == nil {
 | 
			
		||||
			responseWithError(resp, http.StatusBadRequest, errIPv4Only)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		resp.Header().Set("Content-Type", "text/plain")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		server := mapping.Get(ip)
 | 
			
		||||
		log.Printf("%s => %s\n", ip, server)
 | 
			
		||||
		fmt.Fprint(resp, server)
 | 
			
		||||
	})
 | 
			
		||||
	http.HandleFunc("/getNodes", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		ip := req.FormValue("ip")
 | 
			
		||||
		if net.ParseIP(ip).To4() == nil {
 | 
			
		||||
			responseWithError(resp, http.StatusBadRequest, errIPv4Only)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		nodes := mapping.GetNodes()
 | 
			
		||||
		if nodes == nil {
 | 
			
		||||
			responseWithJsonError(resp, http.StatusInternalServerError, "Unable to get nodes")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		suffix := mapping.GetSuffix(ip)
 | 
			
		||||
		resp.Header().Set("Content-Type", "application/json")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		jsonEncoder := json.NewEncoder(resp)
 | 
			
		||||
		ret := make([]string, 0, len(nodes))
 | 
			
		||||
		for _, node := range nodes {
 | 
			
		||||
			ret = append(ret, node+suffix)
 | 
			
		||||
		}
 | 
			
		||||
		jsonEncoder.Encode(ret)
 | 
			
		||||
	})
 | 
			
		||||
	clientApi := http.NewServeMux()
 | 
			
		||||
	http.Handle("/client/", http.StripPrefix("/client", clientApi))
 | 
			
		||||
	clientV1Api := http.NewServeMux()
 | 
			
		||||
	clientApi.Handle("/v1/", http.StripPrefix("/v1", clientV1Api))
 | 
			
		||||
	clientV1Api.HandleFunc("/getNodes", func(resp http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		host := getRemoteIP(req)
 | 
			
		||||
		nodes := mapping.GetNodes()
 | 
			
		||||
		if nodes == nil {
 | 
			
		||||
			responseWithJsonError(resp, http.StatusInternalServerError, "Unable to get nodes")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		suffix := mapping.GetSuffix(host)
 | 
			
		||||
		resp.Header().Set("Content-Type", "application/json")
 | 
			
		||||
		resp.WriteHeader(http.StatusOK)
 | 
			
		||||
		jsonEncoder := json.NewEncoder(resp)
 | 
			
		||||
		jsonEncoder.Encode(map[string]interface{}{
 | 
			
		||||
			"nodes":  nodes,
 | 
			
		||||
			"suffix": suffix,
 | 
			
		||||
		})
 | 
			
		||||
	})
 | 
			
		||||
	log.Println("HTTP server is running on", *listen_spec)
 | 
			
		||||
	http.ListenAndServe(*listen_spec, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -143,14 +143,7 @@ func reload() {
 | 
			
		||||
	parsedFunc = &globals
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetMapping(ip string) string {
 | 
			
		||||
	thread := pool.Get()
 | 
			
		||||
	ret, err := starlark.Call(thread, (*parsedFunc)["getMapping"],
 | 
			
		||||
		starlark.Tuple{starlark.String(ip)}, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Println("Starlark execute error:", err.Error())
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
func getTarget(ret starlark.Value) string {
 | 
			
		||||
	switch r := ret.(type) {
 | 
			
		||||
	case starlark.String:
 | 
			
		||||
		return string(r)
 | 
			
		||||
@ -205,6 +198,17 @@ scriptError:
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetMapping(ip string) string {
 | 
			
		||||
	thread := pool.Get()
 | 
			
		||||
	ret, err := starlark.Call(thread, (*parsedFunc)["getMapping"],
 | 
			
		||||
		starlark.Tuple{starlark.String(ip)}, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Println("Starlark execute error:", err.Error())
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	return getTarget(ret)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetNodes() (res []string) {
 | 
			
		||||
	thread := pool.Get()
 | 
			
		||||
	ret, err := starlark.Call(thread, (*parsedFunc)["getNodes"], nil, nil)
 | 
			
		||||
@ -215,12 +219,11 @@ func GetNodes() (res []string) {
 | 
			
		||||
	if r, ok := ret.(*starlark.List); ok {
 | 
			
		||||
		res = make([]string, r.Len())
 | 
			
		||||
		for i := 0; i < r.Len(); i++ {
 | 
			
		||||
			v := r.Index(i)
 | 
			
		||||
			if s, ok := v.(starlark.String); ok {
 | 
			
		||||
				res[i] = string(s)
 | 
			
		||||
			} else {
 | 
			
		||||
			res[i] = getTarget(r.Index(i))
 | 
			
		||||
			if res[i] == "" {
 | 
			
		||||
				log.Println("Script returned unexpected result:",
 | 
			
		||||
					ret.String())
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,9 @@ HETZNER_FSN_1GE         = "ge-fsn1-de"
 | 
			
		||||
HETZNER_HEL_1GE         = "ge-hel1-fi"
 | 
			
		||||
CLOUDCONE_LAX1_1GE		= "ge-lax1-us"
 | 
			
		||||
CLOUDCONE_LAX2_1GE		= "ge-lax2-us"
 | 
			
		||||
CLOUDCONE_LAX_LB		= (CLOUDCONE_LAX1_1GE, CLOUDCONE_LAX2_1GE)
 | 
			
		||||
CLOUDCONE_LAX3_1GE		= "ge-lax3-us"
 | 
			
		||||
HOSTSOLUTIONS_OMR1_1GE  = "ge-omr1-ro"
 | 
			
		||||
CLOUDCONE_LAX_LB		= (CLOUDCONE_LAX1_1GE, CLOUDCONE_LAX2_1GE, CLOUDCONE_LAX3_1GE)
 | 
			
		||||
default_server          = WHOLESALE_INTERNET_10GE
 | 
			
		||||
 | 
			
		||||
CHINA_MAINLAND_SUFFIX = ".eveedge.link"
 | 
			
		||||
@ -30,7 +32,7 @@ def getMapping(ip):
 | 
			
		||||
	return default_server
 | 
			
		||||
 | 
			
		||||
def getNodes():
 | 
			
		||||
	return ["xe-mci1-us", "ge-fsn1-de", "ge-lax1-us"]
 | 
			
		||||
	return [WHOLESALE_INTERNET_10GE, HETZNER_FSN_1GE, CLOUDCONE_LAX_LB, HOSTSOLUTIONS_OMR1_1GE]
 | 
			
		||||
 | 
			
		||||
def getSuffix(ip):
 | 
			
		||||
	info = geoLookup(ip)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								utils/BUILD.bazel
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								utils/BUILD.bazel
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = ["utils.go"],
 | 
			
		||||
    importpath = "git.eve.moe/jackyyf/navigator/utils",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    deps = ["@com_github_ipipdotnet_ipdb_go//:go_default_library"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										67
									
								
								utils/utils.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								utils/utils.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/ipipdotnet/ipdb-go"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	remoteAddrHeader = "X-NAV-REMOTE-IP"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type errorMessage struct {
 | 
			
		||||
	Error string `json:"error"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ResponseWithError(resp http.ResponseWriter, statusCode int, message string) {
 | 
			
		||||
	resp.Header().Set("Content-Type", "text/plain")
 | 
			
		||||
	resp.WriteHeader(statusCode)
 | 
			
		||||
	resp.Write([]byte("error: " + message))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ResponseWithJsonError(resp http.ResponseWriter, statusCode int, message string) {
 | 
			
		||||
	resp.Header().Set("Content-Type", "application/json")
 | 
			
		||||
	resp.WriteHeader(statusCode)
 | 
			
		||||
	encoder := json.NewEncoder(resp)
 | 
			
		||||
	err := encoder.Encode(&errorMessage{
 | 
			
		||||
		Error: message,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// This should never happen
 | 
			
		||||
		panic("json marshal failed, check code")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetRemoteIP(req *http.Request) string {
 | 
			
		||||
	if addr := req.Header.Get(remoteAddrHeader); addr != "" {
 | 
			
		||||
		if net.ParseIP(addr).To4() == nil {
 | 
			
		||||
			return ""
 | 
			
		||||
		}
 | 
			
		||||
		return addr
 | 
			
		||||
	}
 | 
			
		||||
	host, _, err := net.SplitHostPort(req.RemoteAddr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	if net.ParseIP(host).To4() == nil {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	return host
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func BuildLocation(info *ipdb.CityInfo) string {
 | 
			
		||||
	ret := ""
 | 
			
		||||
	if info.CountryName != "" {
 | 
			
		||||
		ret += info.CountryName + " "
 | 
			
		||||
	}
 | 
			
		||||
	if info.RegionName != "" {
 | 
			
		||||
		ret += info.RegionName + " "
 | 
			
		||||
	}
 | 
			
		||||
	if info.CityName != "" {
 | 
			
		||||
		ret += info.CityName + " "
 | 
			
		||||
	}
 | 
			
		||||
	return strings.TrimSpace(ret)
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user