diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..c9b3654
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,666 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ChangeListManager">
+    <list default="true" id="7b2294ae-6f3a-49d8-aeef-84eab0f3c4d1" name="Default" comment="">
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/bin/anyproxy" afterPath="$PROJECT_DIR$/bin/anyproxy" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/requestHandler.js" afterPath="$PROJECT_DIR$/lib/requestHandler.js" />
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/proxy.js" afterPath="$PROJECT_DIR$/proxy.js" />
+    </list>
+    <ignored path="$PROJECT_DIR$/.tmp/" />
+    <ignored path="$PROJECT_DIR$/temp/" />
+    <ignored path="$PROJECT_DIR$/tmp/" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="TRACKING_ENABLED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="FileEditorManager">
+    <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
+      <file leaf-file-name="proxy.js" pinned="false" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/proxy.js">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="363">
+              <caret line="386" column="0" lean-forward="true" selection-start-line="386" selection-start-column="0" selection-end-line="386" selection-end-column="0" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+    </leaf>
+  </component>
+  <component name="FileTemplateManagerImpl">
+    <option name="RECENT_TEMPLATES">
+      <list>
+        <option value="JavaScript File" />
+        <option value="CSS File" />
+      </list>
+    </option>
+  </component>
+  <component name="FindInProjectRecents">
+    <findStrings>
+      <find>beforeSendRequest</find>
+      <find>_directlyPassToRespond</find>
+      <find>certMgr</find>
+      <find>util</find>
+      <find>options</find>
+      <find>guideToGenrateCA</find>
+      <find>generateRootCA</find>
+      <find>open</find>
+      <find>anyproxy_internal_https_server</find>
+      <find>openFolderOfFile</find>
+      <find>qrcode-npm</find>
+      <find>before</find>
+      <find>beforeSendResponse</find>
+      <find>colorful</find>
+      <find>color</find>
+      <find>node-easy-cert</find>
+      <find>EasyCert</find>
+      <find>easyCert</find>
+      <find>generateCertsForHostname</find>
+      <find>for (const connItem of this.requestHandler.conns)</find>
+      <find>const userRule = util.merge(default_rule, rule);</find>
+      <find>const userModifiedInfo = (yield userRule.beforeSendRequest(Object.assign({}, requestDetail))) || {};</find>
+      <find>// TODO: err etimeout</find>
+      <find>let errorResponse = getErrorResponse(error, fullUrl);</find>
+      <find>shouldIntercept = yield userRule.beforeDealHttpsRequest(requestDetail)</find>
+      <find>* @param {object} rule</find>
+      <find>userRule</find>
+      <find>rule</find>
+      <find>port</find>
+      <find>web</find>
+    </findStrings>
+    <dirStrings>
+      <dir>$PROJECT_DIR$</dir>
+      <dir>$PROJECT_DIR$/src</dir>
+    </dirStrings>
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="IdeDocumentHistory">
+    <option name="CHANGED_PATHS">
+      <list>
+        <option value="$PROJECT_DIR$/.babelrc" />
+        <option value="$PROJECT_DIR$/proxy.es6" />
+        <option value="$PROJECT_DIR$/bin/anyproxy-ca" />
+        <option value="$PROJECT_DIR$/src/proxy.js" />
+        <option value="$PROJECT_DIR$/src/recorder.js" />
+        <option value="$PROJECT_DIR$/web/src/component/json-editor.jsx.js" />
+        <option value="$PROJECT_DIR$/web/src/component/json-editor.css" />
+        <option value="$PROJECT_DIR$/web/src/component/json-editor.less" />
+        <option value="$PROJECT_DIR$/web/src/component/json-viewer.jsx" />
+        <option value="$PROJECT_DIR$/web/webpack.config.js" />
+        <option value="$PROJECT_DIR$/web/src/component/left-menu.less" />
+        <option value="$PROJECT_DIR$/web/src/component/left-menu.jsx" />
+        <option value="$PROJECT_DIR$/web/src/component/header-menu.jsx" />
+        <option value="$PROJECT_DIR$/web/src/component/header-menu.less" />
+        <option value="$PROJECT_DIR$/web/src/component/json-editor.jsx" />
+        <option value="$PROJECT_DIR$/src/requestHandler.js" />
+        <option value="$PROJECT_DIR$/package.json" />
+        <option value="$PROJECT_DIR$/bin/anyproxy" />
+        <option value="$PROJECT_DIR$/lib/requestHandler.js" />
+        <option value="$PROJECT_DIR$/proxy.js" />
+      </list>
+    </option>
+  </component>
+  <component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
+  <component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER">
+    <package-json value="$PROJECT_DIR$/package.json" />
+  </component>
+  <component name="JsFlowSettings">
+    <service-enabled>false</service-enabled>
+    <exe-path />
+    <annotation-enable>false</annotation-enable>
+    <other-services-enabled>false</other-services-enabled>
+    <auto-save>true</auto-save>
+  </component>
+  <component name="JsGulpfileManager">
+    <detection-done>true</detection-done>
+    <sorting>DEFINITION_ORDER</sorting>
+  </component>
+  <component name="ProjectFrameBounds">
+    <option name="x" value="210" />
+    <option name="y" value="63" />
+    <option name="width" value="1365" />
+    <option name="height" value="848" />
+  </component>
+  <component name="ProjectInspectionProfilesVisibleTreeState">
+    <entry key="Project Default">
+      <profile-state>
+        <expanded-state>
+          <State>
+            <id />
+          </State>
+          <State>
+            <id>General</id>
+          </State>
+          <State>
+            <id>XPath</id>
+          </State>
+        </expanded-state>
+      </profile-state>
+    </entry>
+  </component>
+  <component name="ProjectView">
+    <navigator currentView="ProjectPane" proportions="" version="1">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+      <manualOrder />
+      <foldersAlwaysOnTop value="true" />
+    </navigator>
+    <panes>
+      <pane id="Scope" />
+      <pane id="Scratches" />
+      <pane id="ProjectPane">
+        <subPane>
+          <expand>
+            <path>
+              <item name="anyproxy" type="b2602c69:ProjectViewProjectNode" />
+              <item name="anyproxy" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="anyproxy" type="b2602c69:ProjectViewProjectNode" />
+              <item name="anyproxy" type="462c0819:PsiDirectoryNode" />
+              <item name="bin" type="462c0819:PsiDirectoryNode" />
+            </path>
+            <path>
+              <item name="anyproxy" type="b2602c69:ProjectViewProjectNode" />
+              <item name="anyproxy" type="462c0819:PsiDirectoryNode" />
+              <item name="lib" type="462c0819:PsiDirectoryNode" />
+            </path>
+          </expand>
+          <select />
+        </subPane>
+      </pane>
+    </panes>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="settings.editor.selected.configurable" value="Errors" />
+    <property name="settings.editor.splitter.proportion" value="0.2" />
+    <property name="WebServerToolWindowFactoryState" value="false" />
+    <property name="nodejs_interpreter_path" value="$USER_HOME$/git/nvs/default/bin/node" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+    <property name="HbShouldOpenHtmlAsHb" value="" />
+    <property name="node.js.path.for.package.eslint" value="project" />
+    <property name="node.js.detected.package.eslint" value="true" />
+    <property name="node.js.selected.package.eslint" value="$PROJECT_DIR$/node_modules/eslint" />
+    <property name="SearchEverywhereHistoryKey" value="&#9;FILE&#9;file:///Users/guobingjian/workspace/anyproxy/web/src/component/header-menu.jsx&#10;ifRootCAFileExists&#9;null&#9;null&#10;requestHandler&#9;FILE&#9;file:///Users/guobingjian/workspace/anyproxy/src/requestHandler.js" />
+    <property name="list.type.of.created.stylesheet" value="CSS" />
+  </component>
+  <component name="RecentsManager">
+    <key name="MoveFile.RECENT_KEYS">
+      <recent name="$PROJECT_DIR$" />
+      <recent name="$PROJECT_DIR$/src" />
+    </key>
+    <key name="CopyFile.RECENT_KEYS">
+      <recent name="$PROJECT_DIR$" />
+      <recent name="$PROJECT_DIR$/src" />
+    </key>
+  </component>
+  <component name="RunDashboard">
+    <option name="ruleStates">
+      <list>
+        <RuleState>
+          <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+        </RuleState>
+        <RuleState>
+          <option name="name" value="StatusDashboardGroupingRule" />
+        </RuleState>
+      </list>
+    </option>
+  </component>
+  <component name="ShelveChangesManager" show_recycled="false">
+    <option name="remove_strategy" value="false" />
+  </component>
+  <component name="SvnConfiguration">
+    <configuration />
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="7b2294ae-6f3a-49d8-aeef-84eab0f3c4d1" name="Default" comment="" />
+      <created>1501480909284</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1501480909284</updated>
+      <workItem from="1501480910518" duration="827000" />
+      <workItem from="1503564523259" duration="269000" />
+      <workItem from="1503576423278" duration="4000" />
+      <workItem from="1504603300023" duration="17960000" />
+      <workItem from="1504782401909" duration="675000" />
+      <workItem from="1505131732257" duration="5247000" />
+      <workItem from="1505225523430" duration="394000" />
+      <workItem from="1505274563093" duration="958000" />
+      <workItem from="1505290241520" duration="3442000" />
+      <workItem from="1505354165356" duration="6494000" />
+      <workItem from="1505455728372" duration="6011000" />
+      <workItem from="1506060674044" duration="10054000" />
+      <workItem from="1506071934483" duration="173000" />
+      <workItem from="1506074137653" duration="464000" />
+      <workItem from="1506078200095" duration="16000" />
+      <workItem from="1506258470976" duration="3114000" />
+      <workItem from="1508403794507" duration="164000" />
+      <workItem from="1508415068445" duration="2289000" />
+      <workItem from="1508730960495" duration="2482000" />
+      <workItem from="1508740962206" duration="42000" />
+      <workItem from="1509452805028" duration="673000" />
+      <workItem from="1509553445414" duration="662000" />
+      <workItem from="1509714936935" duration="1573000" />
+      <workItem from="1509795971791" duration="2281000" />
+      <workItem from="1509941231758" duration="222000" />
+      <workItem from="1510891462146" duration="263000" />
+      <workItem from="1510903754282" duration="431000" />
+      <workItem from="1511158423405" duration="29000" />
+      <workItem from="1511158481499" duration="612000" />
+      <workItem from="1511419037136" duration="823000" />
+      <workItem from="1514425904024" duration="3324000" />
+    </task>
+    <servers />
+  </component>
+  <component name="TimeTrackingManager">
+    <option name="totallyTimeSpent" value="71972000" />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="210" y="63" width="1365" height="848" extended-state="0" />
+    <layout>
+      <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25892857" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.34794158" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.32934928" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="npm" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+    </layout>
+  </component>
+  <component name="TypeScriptGeneratedFilesManager">
+    <option name="version" value="1" />
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager>
+      <option name="time" value="5" />
+    </breakpoint-manager>
+    <watches-manager />
+  </component>
+  <component name="editorHistoryManager">
+    <entry file="file://$PROJECT_DIR$/.github/ISSUE_TEMPLATE.md">
+      <provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
+        <state split_layout="SPLIT">
+          <first_editor relative-caret-position="0">
+            <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          </first_editor>
+          <second_editor>
+            <js_state />
+          </second_editor>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/proxy.es6" />
+    <entry file="file://$PROJECT_DIR$/node_modules/events/events.js" />
+    <entry file="file://$PROJECT_DIR$/src/rule_default.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="243">
+          <caret line="41" column="3" lean-forward="false" selection-start-line="41" selection-start-column="3" selection-end-line="41" selection-end-column="3" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/wsServer.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="266">
+          <caret line="14" column="20" lean-forward="false" selection-start-line="14" selection-start-column="20" selection-end-line="14" selection-end-column="20" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/util.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="262">
+          <caret line="40" column="1" lean-forward="false" selection-start-line="40" selection-start-column="1" selection-end-line="40" selection-end-column="1" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/record-detail.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="114">
+          <caret line="9" column="7" lean-forward="false" selection-start-line="9" selection-start-column="7" selection-end-line="9" selection-end-column="7" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/style/animate.less">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/json-editor.less" />
+    <entry file="file://$PROJECT_DIR$/web/src/component/json-viewer.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-1350">
+          <caret line="8" column="35" lean-forward="false" selection-start-line="8" selection-start-column="35" selection-end-line="8" selection-end-column="35" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/webpack.config.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="247">
+          <caret line="87" column="6" lean-forward="true" selection-start-line="87" selection-start-column="6" selection-end-line="87" selection-end-column="6" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/left-menu.less">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="211">
+          <caret line="139" column="62" lean-forward="true" selection-start-line="139" selection-start-column="12" selection-end-line="139" selection-end-column="62" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/header-menu.less">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="308">
+          <caret line="73" column="3" lean-forward="true" selection-start-line="73" selection-start-column="3" selection-end-line="73" selection-end-column="3" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/json-editor.jsx" />
+    <entry file="file://$PROJECT_DIR$/web/src/common/ApiUtil.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="-278">
+          <caret line="15" column="1" lean-forward="true" selection-start-line="15" selection-start-column="1" selection-end-line="15" selection-end-column="1" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/left-menu.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="347">
+          <caret line="134" column="15" lean-forward="false" selection-start-line="134" selection-start-column="15" selection-end-line="134" selection-end-column="15" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/download-root-ca.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="139">
+          <caret line="11" column="19" lean-forward="false" selection-start-line="11" selection-start-column="9" selection-end-line="11" selection-end-column="19" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/action/globalStatusAction.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="2964">
+          <caret line="156" column="26" lean-forward="false" selection-start-line="156" selection-start-column="16" selection-end-line="156" selection-end-column="26" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/header-menu.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="5472">
+          <caret line="292" column="15" lean-forward="false" selection-start-line="292" selection-start-column="15" selection-end-line="292" selection-end-column="15" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/reducer/globalStatusReducer.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/reducer/requestRecordReducer.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="456">
+          <caret line="24" column="27" lean-forward="false" selection-start-line="24" selection-start-column="9" selection-end-line="24" selection-end-column="27" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/reducer/rootReducer.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="171">
+          <caret line="9" column="43" lean-forward="false" selection-start-line="9" selection-start-column="23" selection-end-line="9" selection-end-column="43" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/saga/rootSaga.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="2318">
+          <caret line="122" column="30" lean-forward="false" selection-start-line="122" selection-start-column="30" selection-end-line="122" selection-end-column="30" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/action/recordAction.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="42" column="33" lean-forward="false" selection-start-line="42" selection-start-column="16" selection-end-line="42" selection-end-column="33" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/component/record-panel.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="209">
+          <caret line="13" column="17" lean-forward="false" selection-start-line="13" selection-start-column="6" selection-end-line="13" selection-end-column="17" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/web/src/index.jsx">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="893">
+          <caret line="47" column="43" lean-forward="false" selection-start-line="47" selection-start-column="43" selection-end-line="47" selection-end-column="43" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lib/util.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="238">
+          <caret line="50" column="0" lean-forward="false" selection-start-line="50" selection-start-column="0" selection-end-line="50" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lib/proxy.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="413">
+          <caret line="114" column="56" lean-forward="false" selection-start-line="114" selection-start-column="56" selection-end-line="114" selection-end-column="56" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/systemProxyMgr.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lib/recorder.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1748">
+          <caret line="92" column="19" lean-forward="false" selection-start-line="92" selection-start-column="19" selection-end-line="92" selection-end-column="19" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/recorder.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1311">
+          <caret line="69" column="56" lean-forward="false" selection-start-line="69" selection-start-column="12" selection-end-line="69" selection-end-column="56" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/rule_sample/sample_modify_response_data.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/rule_sample/sample_modify_request_data.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/rule_sample/sample_modify_request_header.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/rule_sample/sample_modify_request_path.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/rule_sample/sample_modify_request_protocol.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/rule_sample/sample_use_local_response.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="76">
+          <caret line="9" column="5" lean-forward="false" selection-start-line="9" selection-start-column="5" selection-end-line="11" selection-end-column="49" />
+          <folding>
+            <element signature="n#!!doc" expanded="false" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/bin/anyproxy-ca">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="209">
+          <caret line="11" column="0" lean-forward="false" selection-start-line="11" selection-start-column="0" selection-end-line="11" selection-end-column="43" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/httpsServerMgr.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1425">
+          <caret line="75" column="28" lean-forward="false" selection-start-line="75" selection-start-column="28" selection-end-line="75" selection-end-column="28" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/webInterface.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="3819">
+          <caret line="201" column="30" lean-forward="false" selection-start-line="201" selection-start-column="30" selection-end-line="201" selection-end-column="30" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/requestHandler.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="323">
+          <caret line="17" column="29" lean-forward="false" selection-start-line="17" selection-start-column="29" selection-end-line="17" selection-end-column="29" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/log.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="38">
+          <caret line="2" column="0" lean-forward="false" selection-start-line="2" selection-start-column="0" selection-end-line="2" selection-end-column="34" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/certMgr.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="247">
+          <caret line="13" column="3" lean-forward="true" selection-start-line="13" selection-start-column="3" selection-end-line="13" selection-end-column="3" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lib/certMgr.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="1314">
+          <caret line="95" column="24" lean-forward="false" selection-start-line="95" selection-start-column="24" selection-end-line="95" selection-end-column="24" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/proxy.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="171">
+          <caret line="9" column="32" lean-forward="false" selection-start-line="9" selection-start-column="32" selection-end-line="9" selection-end-column="32" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/.eslintignore">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/test.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="0">
+          <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/package.json">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="576">
+          <caret line="111" column="4" lean-forward="false" selection-start-line="111" selection-start-column="4" selection-end-line="111" selection-end-column="4" />
+          <folding>
+            <marker date="1514431766024" expanded="true" signature="3225:3230" ph="{&quot;test&quot;: &quot;node test.js&quot;...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/lib/requestHandler.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="406">
+          <caret line="632" column="0" lean-forward="true" selection-start-line="632" selection-start-column="0" selection-end-line="632" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/bin/anyproxy">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="393">
+          <caret line="114" column="0" lean-forward="true" selection-start-line="114" selection-start-column="0" selection-end-line="114" selection-end-column="0" />
+          <folding>
+            <marker date="1514431806400" expanded="true" signature="1188:3202" ph="{...}" />
+          </folding>
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/proxy.js">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="363">
+          <caret line="386" column="0" lean-forward="true" selection-start-line="386" selection-start-column="0" selection-end-line="386" selection-end-column="0" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+  </component>
+</project>
\ No newline at end of file
diff --git a/bin/anyproxy b/bin/anyproxy
index 330e083..d1831bd 100755
--- a/bin/anyproxy
+++ b/bin/anyproxy
@@ -46,37 +46,37 @@ if (program.clear) {
       resolve(null);
     }
   })
-  .catch(e => {
-    logUtil.printLog('Failed to load rule file', logUtil.T_ERR);
-    logUtil.printLog(e, logUtil.T_ERR);
-    process.exit();
-  })
+    .catch(e => {
+      logUtil.printLog('Failed to load rule file', logUtil.T_ERR);
+      logUtil.printLog(e, logUtil.T_ERR);
+      process.exit();
+    })
 
-  //start proxy
-  .then(ruleModule => {
-    proxyServer = new AnyProxy.ProxyServer({
-      type: 'http',
-      port: program.port || 8001,
-      throttle: program.throttle,
-      rule: ruleModule,
-      webInterface: {
-        enable: true,
-        webPort: program.web,
-      },        
-      forceProxyHttps: program.intercept,
-      dangerouslyIgnoreUnauthorized: !!program.ignoreUnauthorizedSsl,
-      silent: program.silent
+    //start proxy
+    .then(ruleModule => {
+      proxyServer = new AnyProxy.ProxyServer({
+        type: 'http',
+        port: program.port || 8001,
+        throttle: program.throttle,
+        rule: ruleModule,
+        webInterface: {
+          enable: true,
+          webPort: program.web,
+        },
+        forceProxyHttps: program.intercept,
+        dangerouslyIgnoreUnauthorized: !!program.ignoreUnauthorizedSsl,
+        silent: program.silent
+      });
+      // proxyServer.on('ready', () => {});
+      proxyServer.start();
+    })
+    .catch(e => {
+      logUtil.printLog(e, logUtil.T_ERR);
+      if (e && e.code) {
+        logUtil.printLog('code ' + e.code, logUtil.T_ERR);
+      }
+      logUtil.printLog(e.stack, logUtil.T_ERR);
     });
-    // proxyServer.on('ready', () => {});
-    proxyServer.start();
-  })
-  .catch(e => {
-    logUtil.printLog(e, logUtil.T_ERR);
-    if (e && e.code) {
-      logUtil.printLog('code ' + e.code, logUtil.T_ERR);
-    }
-    logUtil.printLog(e.stack, logUtil.T_ERR);
-  });
 
   process.on('exit', (code) => {
     if (code > 0) {
@@ -107,7 +107,7 @@ if (program.clear) {
     } catch (e) {}
     logUtil.printLog(errorTipText, logUtil.T_ERR);
     try {
-      proxyServer && proxyServer.close();        
+      proxyServer && proxyServer.close();
     } catch (e) {}
     process.exit();
   });
diff --git a/lib/requestHandler.js b/lib/requestHandler.js
index ecde92b..2335891 100644
--- a/lib/requestHandler.js
+++ b/lib/requestHandler.js
@@ -252,13 +252,13 @@ function getUserReqHandler(userRule, recorder) {
     };
 
     /**
-    * send response to client
-    *
-    * @param {object} finalResponseData
-    * @param {number} finalResponseData.statusCode
-    * @param {object} finalResponseData.header
-    * @param {buffer|string} finalResponseData.body
-    */
+     * send response to client
+     *
+     * @param {object} finalResponseData
+     * @param {number} finalResponseData.statusCode
+     * @param {object} finalResponseData.header
+     * @param {buffer|string} finalResponseData.body
+     */
     const sendFinalResponse = (finalResponseData) => {
       const responseInfo = finalResponseData.response;
       const resHeader = responseInfo.header;
@@ -297,7 +297,7 @@ function getUserReqHandler(userRule, recorder) {
       if (!global._throttle
         && transferEncoding !== 'chunked'
         && !(responseBody instanceof CommonReadableStream)
-        ) {
+      ) {
         resHeader['Content-Length'] = util.getByteSize(responseBody);
       }
 
@@ -479,119 +479,119 @@ function getConnectReqHandler(userRule, recorder, httpsServerMgr) {
         shouldIntercept = yield userRule.beforeDealHttpsRequest(requestDetail);
       }
     })
-    .then(() =>
-      new Promise((resolve) => {
-        // mark socket connection as established, to detect the request protocol
-        cltSocket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', resolve);
-      })
-    )
-    .then(() =>
-      new Promise((resolve, reject) => {
-        let resolved = false;
-        cltSocket.on('data', (chunk) => {
-          requestStream.push(chunk);
-          if (!resolved) {
-            resolved = true;
-            try {
-              const chunkString = chunk.toString();
-              if (chunkString.indexOf('GET ') === 0) {
-                shouldIntercept = false; //websocket
+      .then(() =>
+        new Promise((resolve) => {
+          // mark socket connection as established, to detect the request protocol
+          cltSocket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', resolve);
+        })
+      )
+      .then(() =>
+        new Promise((resolve, reject) => {
+          let resolved = false;
+          cltSocket.on('data', (chunk) => {
+            requestStream.push(chunk);
+            if (!resolved) {
+              resolved = true;
+              try {
+                const chunkString = chunk.toString();
+                if (chunkString.indexOf('GET ') === 0) {
+                  shouldIntercept = false; //websocket
+                }
+              } catch (e) {
+                console.error(e);
               }
-            } catch (e) {
-              console.error(e);
+              resolve();
             }
-            resolve();
+          });
+          cltSocket.on('end', () => {
+            requestStream.push(null);
+          });
+        })
+      )
+      .then((result) => {
+        // log and recorder
+        if (shouldIntercept) {
+          logUtil.printLog('will forward to local https server');
+        } else {
+          logUtil.printLog('will bypass the man-in-the-middle proxy');
+        }
+
+        //record
+        if (recorder) {
+          resourceInfo = {
+            host,
+            method: req.method,
+            path: '',
+            url: 'https://' + host,
+            req,
+            startTime: new Date().getTime()
+          };
+          resourceInfoId = recorder.appendRecord(resourceInfo);
+        }
+      })
+      .then(() => {
+        // determine the request target
+        if (!shouldIntercept) {
+          return {
+            host,
+            port: (targetPort === 80) ? 443 : targetPort,
           }
-        });
-        cltSocket.on('end', () => {
-          requestStream.push(null);
+        } else {
+          return httpsServerMgr.getSharedHttpsServer(host).then(serverInfo => ({ host: serverInfo.host, port: serverInfo.port }));
+        }
+      })
+      .then((serverInfo) => {
+        if (!serverInfo.port || !serverInfo.host) {
+          throw new Error('failed to get https server info');
+        }
+
+        return new Promise((resolve, reject) => {
+          const conn = net.connect(serverInfo.port, serverInfo.host, () => {
+            //throttle for direct-foward https
+            if (global._throttle && !shouldIntercept) {
+              requestStream.pipe(conn);
+              conn.pipe(global._throttle.throttle()).pipe(cltSocket);
+            } else {
+              requestStream.pipe(conn);
+              conn.pipe(cltSocket);
+            }
+
+            resolve();
+          });
+
+          conn.on('error', (e) => {
+            reject(e);
+          });
+
+          reqHandlerCtx.conns.set(serverInfo.host + ':' + serverInfo.port, conn)
+          reqHandlerCtx.cltSockets.set(serverInfo.host + ':' + serverInfo.port, cltSocket)
         });
       })
-    )
-    .then((result) => {
-      // log and recorder
-      if (shouldIntercept) {
-        logUtil.printLog('will forward to local https server');
-      } else {
-        logUtil.printLog('will bypass the man-in-the-middle proxy');
-      }
+      .then(() => {
+        if (recorder) {
+          resourceInfo.endTime = new Date().getTime();
+          resourceInfo.statusCode = '200';
+          resourceInfo.resHeader = {};
+          resourceInfo.resBody = '';
+          resourceInfo.length = 0;
 
-      //record
-      if (recorder) {
-        resourceInfo = {
-          host,
-          method: req.method,
-          path: '',
-          url: 'https://' + host,
-          req,
-          startTime: new Date().getTime()
-        };
-        resourceInfoId = recorder.appendRecord(resourceInfo);
-      }
-    })
-    .then(() => {
-      // determine the request target
-      if (!shouldIntercept) {
-        return {
-          host,
-          port: (targetPort === 80) ? 443 : targetPort,
+          recorder && recorder.updateRecord(resourceInfoId, resourceInfo);
         }
-      } else {
-        return httpsServerMgr.getSharedHttpsServer(host).then(serverInfo => ({ host: serverInfo.host, port: serverInfo.port }));
-      }
-    })
-    .then((serverInfo) => {
-      if (!serverInfo.port || !serverInfo.host) {
-        throw new Error('failed to get https server info');
-      }
+      })
+      .catch(co.wrap(function *(error) {
+        logUtil.printLog(util.collectErrorLog(error), logUtil.T_ERR);
 
-      return new Promise((resolve, reject) => {
-        const conn = net.connect(serverInfo.port, serverInfo.host, () => {
-          //throttle for direct-foward https
-          if (global._throttle && !shouldIntercept) {
-            requestStream.pipe(conn);
-            conn.pipe(global._throttle.throttle()).pipe(cltSocket);
-          } else {
-            requestStream.pipe(conn);
-            conn.pipe(cltSocket);
-          }
+        try {
+          yield userRule.onConnectError(requestDetail, error);
+        } catch (e) { }
 
-          resolve();
-        });
-
-        conn.on('error', (e) => {
-          reject(e);
-        });
-
-        reqHandlerCtx.conns.set(serverInfo.host + ':' + serverInfo.port, conn)
-        reqHandlerCtx.cltSockets.set(serverInfo.host + ':' + serverInfo.port, cltSocket)
-      });
-    })
-    .then(() => {
-      if (recorder) {
-        resourceInfo.endTime = new Date().getTime();
-        resourceInfo.statusCode = '200';
-        resourceInfo.resHeader = {};
-        resourceInfo.resBody = '';
-        resourceInfo.length = 0;
-
-        recorder && recorder.updateRecord(resourceInfoId, resourceInfo);
-      }
-    })
-    .catch(co.wrap(function *(error) {
-      logUtil.printLog(util.collectErrorLog(error), logUtil.T_ERR);
-
-      try {
-        yield userRule.onConnectError(requestDetail, error);
-      } catch (e) { }
-
-      try {
-        let errorHeader = 'Proxy-Error: true\r\n';
-        errorHeader += 'Proxy-Error-Message: ' + (error || 'null') + '\r\n';
-        errorHeader += 'Content-Type: text/html\r\n';
-        cltSocket.write('HTTP/1.1 502\r\n' + errorHeader + '\r\n\r\n');
-      } catch (e) { }
-    }));
+        try {
+          let errorHeader = 'Proxy-Error: true\r\n';
+          errorHeader += 'Proxy-Error-Message: ' + (error || 'null') + '\r\n';
+          errorHeader += 'Content-Type: text/html\r\n';
+          cltSocket.write('HTTP/1.1 502\r\n' + errorHeader + '\r\n\r\n');
+        } catch (e) { }
+      }));
   }
 }
 
diff --git a/proxy.js b/proxy.js
index bf495d5..64604cf 100644
--- a/proxy.js
+++ b/proxy.js
@@ -120,15 +120,15 @@ class ProxyCore extends events.EventEmitter {
   }
 
   /**
-  * manage all created socket
-  * for each new socket, we put them to a map;
-  * if the socket is closed itself, we remove it from the map
-  * when the `close` method is called, we'll close the sockes before the server closed
-  *
-  * @param {Socket} the http socket that is creating
-  * @returns undefined
-  * @memberOf ProxyCore
-  */
+   * manage all created socket
+   * for each new socket, we put them to a map;
+   * if the socket is closed itself, we remove it from the map
+   * when the `close` method is called, we'll close the sockes before the server closed
+   *
+   * @param {Socket} the http socket that is creating
+   * @returns undefined
+   * @memberOf ProxyCore
+   */
   handleExistConnections(socket) {
     const self = this;
     self.socketIndex ++;
@@ -332,13 +332,13 @@ class ProxyServer extends ProxyCore {
         resolve(null);
       }
     })
-    .then(() => {
-      // start proxy core
-      super.start()
-    })
-    .catch((e) => {
-      this.emit('error', e);
-    });
+      .then(() => {
+        // start proxy core
+        super.start()
+      })
+      .catch((e) => {
+        this.emit('error', e);
+      });
   }
 
   close() {