initial commit
This commit is contained in:
commit
6e49f004cd
|
@ -0,0 +1 @@
|
|||
nodeartnet
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="?*.properties" />
|
||||
<entry name="?*.xml" />
|
||||
<entry name="?*.gif" />
|
||||
<entry name="?*.png" />
|
||||
<entry name="?*.jpeg" />
|
||||
<entry name="?*.jpg" />
|
||||
<entry name="?*.html" />
|
||||
<entry name="?*.dtd" />
|
||||
<entry name="?*.tld" />
|
||||
<entry name="?*.ftl" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<component name="CopyrightManager">
|
||||
<settings default="">
|
||||
<module2copyright />
|
||||
</settings>
|
||||
</component>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="PyConsoleOptionsProvider">
|
||||
<option name="myPythonConsoleState">
|
||||
<PyConsoleSettings />
|
||||
</option>
|
||||
<option name="myDjangoConsoleState">
|
||||
<PyConsoleSettings />
|
||||
</option>
|
||||
</component>
|
||||
<component name="SvnConfiguration" maxAnnotateRevisions="500" myUseAcceleration="nothing" myAutoUpdateAfterCommit="false" cleanupOnStartRun="false">
|
||||
<option name="USER" value="" />
|
||||
<option name="PASSWORD" value="" />
|
||||
<option name="mySSHConnectionTimeout" value="30000" />
|
||||
<option name="mySSHReadTimeout" value="30000" />
|
||||
<option name="LAST_MERGED_REVISION" />
|
||||
<option name="MERGE_DRY_RUN" value="false" />
|
||||
<option name="MERGE_DIFF_USE_ANCESTRY" value="true" />
|
||||
<option name="UPDATE_LOCK_ON_DEMAND" value="false" />
|
||||
<option name="IGNORE_SPACES_IN_MERGE" value="false" />
|
||||
<option name="DETECT_NESTED_COPIES" value="true" />
|
||||
<option name="CHECK_NESTED_FOR_QUICK_MERGE" value="false" />
|
||||
<option name="IGNORE_SPACES_IN_ANNOTATE" value="true" />
|
||||
<option name="SHOW_MERGE_SOURCES_IN_ANNOTATE" value="true" />
|
||||
<option name="FORCE_UPDATE" value="false" />
|
||||
<option name="IGNORE_EXTERNALS" value="false" />
|
||||
<myIsUseDefaultProxy>false</myIsUseDefaultProxy>
|
||||
</component>
|
||||
<component name="masterDetails">
|
||||
<states>
|
||||
<state key="ProjectJDKs.UI">
|
||||
<settings>
|
||||
<last-edited>1.6</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.20000002" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
</states>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/nodeartnet.iml" filepath="$PROJECT_DIR$/nodeartnet.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<state>
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</state>
|
||||
</component>
|
|
@ -0,0 +1,125 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,412 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="72d93b4a-de8e-43f1-9d4b-34713e827c14" name="Default" comment="" />
|
||||
<ignored path="nodeartnet.iws" />
|
||||
<ignored path=".idea/workspace.xml" />
|
||||
<file path="$PROJECT_DIR$/../hackcentercontrol/app.js" changelist="72d93b4a-de8e-43f1-9d4b-34713e827c14" time="1356729852724" ignored="false" />
|
||||
<file path="/app.js" changelist="72d93b4a-de8e-43f1-9d4b-34713e827c14" time="1356732858583" ignored="false" />
|
||||
<file path="/index.html" changelist="72d93b4a-de8e-43f1-9d4b-34713e827c14" time="1356732719044" ignored="false" />
|
||||
<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="ChangesViewManager" flattened_view="true" show_ignored="false" />
|
||||
<component name="CreatePatchCommitExecutor">
|
||||
<option name="PATCH_PATH" value="" />
|
||||
</component>
|
||||
<component name="DaemonCodeAnalyzer">
|
||||
<disable_hints />
|
||||
</component>
|
||||
<component name="DebuggerManager">
|
||||
<breakpoint_any default_suspend_policy="SuspendAll" default_condition_enabled="true">
|
||||
<breakpoint>
|
||||
<option name="NOTIFY_CAUGHT" value="true" />
|
||||
<option name="NOTIFY_UNCAUGHT" value="true" />
|
||||
<option name="ENABLED" value="false" />
|
||||
<option name="LOG_ENABLED" value="false" />
|
||||
<option name="LOG_EXPRESSION_ENABLED" value="false" />
|
||||
<option name="SUSPEND_POLICY" value="SuspendAll" />
|
||||
<option name="SUSPEND" value="true" />
|
||||
<option name="COUNT_FILTER_ENABLED" value="false" />
|
||||
<option name="COUNT_FILTER" value="0" />
|
||||
<option name="CONDITION_ENABLED" value="true" />
|
||||
<option name="CLASS_FILTERS_ENABLED" value="false" />
|
||||
<option name="INSTANCE_FILTERS_ENABLED" value="false" />
|
||||
<option name="CONDITION" value="" />
|
||||
<option name="LOG_MESSAGE" value="" />
|
||||
</breakpoint>
|
||||
<breakpoint>
|
||||
<option name="NOTIFY_CAUGHT" value="true" />
|
||||
<option name="NOTIFY_UNCAUGHT" value="true" />
|
||||
<option name="ENABLED" value="false" />
|
||||
<option name="LOG_ENABLED" value="false" />
|
||||
<option name="LOG_EXPRESSION_ENABLED" value="false" />
|
||||
<option name="SUSPEND_POLICY" value="SuspendAll" />
|
||||
<option name="SUSPEND" value="true" />
|
||||
<option name="COUNT_FILTER_ENABLED" value="false" />
|
||||
<option name="COUNT_FILTER" value="0" />
|
||||
<option name="CONDITION_ENABLED" value="true" />
|
||||
<option name="CLASS_FILTERS_ENABLED" value="false" />
|
||||
<option name="INSTANCE_FILTERS_ENABLED" value="false" />
|
||||
<option name="CONDITION" value="" />
|
||||
<option name="LOG_MESSAGE" value="" />
|
||||
</breakpoint>
|
||||
</breakpoint_any>
|
||||
<breakpoint_rules default_suspend_policy="SuspendAll" default_condition_enabled="true" />
|
||||
<ui_properties default_suspend_policy="SuspendAll" default_condition_enabled="true" />
|
||||
<breakpoint_rules />
|
||||
<ui_properties />
|
||||
</component>
|
||||
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
|
||||
<component name="FavoritesManager">
|
||||
<favorites_list name="nodeartnet" />
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf>
|
||||
<file leaf-file-name="app.js" pinned="false" current="true" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/app.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="43" column="31" selection-start="1224" selection-end="1224" vertical-scroll-proportion="0.8895435">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="index.html" pinned="false" current="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/index.html">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="24" column="96" selection-start="672" selection-end="672" vertical-scroll-proportion="-7.5">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
</leaf>
|
||||
</component>
|
||||
<component name="FindManager">
|
||||
<FindUsagesManager>
|
||||
<setting name="OPEN_NEW_TAB" value="false" />
|
||||
</FindUsagesManager>
|
||||
</component>
|
||||
<component name="IdeDocumentHistory">
|
||||
<option name="changedFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/index.html" />
|
||||
<option value="$PROJECT_DIR$/app.js" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectFrameBounds">
|
||||
<option name="y" value="25" />
|
||||
<option name="width" value="1600" />
|
||||
<option name="height" value="850" />
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectReloadState">
|
||||
<option name="STATE" value="0" />
|
||||
</component>
|
||||
<component name="ProjectView">
|
||||
<navigator currentView="ProjectPane" proportions="" version="1" splitterProportion="0.5">
|
||||
<flattenPackages />
|
||||
<showMembers />
|
||||
<showModules />
|
||||
<showLibraryContents />
|
||||
<hideEmptyPackages />
|
||||
<abbreviatePackageNames />
|
||||
<autoscrollToSource />
|
||||
<autoscrollFromSource />
|
||||
<sortByType />
|
||||
</navigator>
|
||||
<panes>
|
||||
<pane id="ProjectPane">
|
||||
<subPane>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="nodeartnet" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="nodeartnet" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="nodeartnet" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="nodeartnet" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="nodeartnet" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="bootstrap" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="js" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
<PATH>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="nodeartnet" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="nodeartnet" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
<PATH_ELEMENT>
|
||||
<option name="myItemId" value="bootstrap" />
|
||||
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
|
||||
</PATH_ELEMENT>
|
||||
</PATH>
|
||||
</subPane>
|
||||
</pane>
|
||||
<pane id="PackagesPane" />
|
||||
<pane id="Scope" />
|
||||
</panes>
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="GoToFile.includeJavaFiles" value="false" />
|
||||
<property name="GoToClass.toSaveIncludeLibraries" value="false" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<property name="MemberChooser.sorted" value="false" />
|
||||
<property name="MemberChooser.showClasses" value="true" />
|
||||
<property name="GoToClass.includeLibraries" value="false" />
|
||||
<property name="MemberChooser.copyJavadoc" value="false" />
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
|
||||
<module name="" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m" />
|
||||
<option name="PROGRAM_PARAMETERS" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="Remote" factoryName="Remote">
|
||||
<option name="USE_SOCKET_TRANSPORT" value="true" />
|
||||
<option name="SERVER_MODE" value="false" />
|
||||
<option name="SHMEM_ADDRESS" value="javadebug" />
|
||||
<option name="HOST" value="localhost" />
|
||||
<option name="PORT" value="5005" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="Applet" factoryName="Applet">
|
||||
<module name="" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="HTML_FILE_NAME" />
|
||||
<option name="HTML_USED" value="false" />
|
||||
<option name="WIDTH" value="400" />
|
||||
<option name="HEIGHT" value="300" />
|
||||
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="TestNG" factoryName="TestNG">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<module name="" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="SUITE_NAME" />
|
||||
<option name="PACKAGE_NAME" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="METHOD_NAME" />
|
||||
<option name="GROUP_NAME" />
|
||||
<option name="TEST_OBJECT" value="CLASS" />
|
||||
<option name="VM_PARAMETERS" value="-ea" />
|
||||
<option name="PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="OUTPUT_DIRECTORY" />
|
||||
<option name="ANNOTATION_TYPE" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="moduleWithDependencies" />
|
||||
</option>
|
||||
<option name="USE_DEFAULT_REPORTERS" value="false" />
|
||||
<option name="PROPERTIES_FILE" />
|
||||
<envs />
|
||||
<properties />
|
||||
<listeners />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="Application" factoryName="Application">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="VM_PARAMETERS" />
|
||||
<option name="PROGRAM_PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="ENABLE_SWING_INSPECTOR" value="false" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<module name="" />
|
||||
<envs />
|
||||
<method />
|
||||
</configuration>
|
||||
<configuration default="true" type="JUnit" factoryName="JUnit">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<module name="" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="PACKAGE_NAME" />
|
||||
<option name="MAIN_CLASS_NAME" />
|
||||
<option name="METHOD_NAME" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea" />
|
||||
<option name="PARAMETERS" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="ENV_VARIABLES" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="moduleWithDependencies" />
|
||||
</option>
|
||||
<envs />
|
||||
<patterns />
|
||||
<method />
|
||||
</configuration>
|
||||
<list size="0" />
|
||||
<configuration name="<template>" type="WebApp" default="true" selected="false">
|
||||
<Host>localhost</Host>
|
||||
<Port>5050</Port>
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="ShelveChangesManager" show_recycled="false" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="72d93b4a-de8e-43f1-9d4b-34713e827c14" name="Default" comment="" />
|
||||
<created>1356729353747</created>
|
||||
<updated>1356729353747</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="0" y="25" width="1600" height="850" extended-state="6" />
|
||||
<editor active="true" />
|
||||
<layout>
|
||||
<window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" 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" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="true" content_ui="tabs" />
|
||||
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.24967825" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
|
||||
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" 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" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
|
||||
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" 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" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
|
||||
</layout>
|
||||
</component>
|
||||
<component name="VcsContentAnnotationSettings">
|
||||
<option name="myLimit" value="2678400000" />
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
|
||||
<option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
|
||||
<option name="CHECK_NEW_TODO" value="true" />
|
||||
<option name="myTodoPanelSettings">
|
||||
<value>
|
||||
<are-packages-shown value="false" />
|
||||
<are-modules-shown value="false" />
|
||||
<flatten-packages value="false" />
|
||||
<is-autoscroll-to-source value="false" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="PERFORM_UPDATE_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_COMMIT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_EDIT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_CHECKOUT_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_ADD_REMOVE_IN_BACKGROUND" value="true" />
|
||||
<option name="PERFORM_ROLLBACK_IN_BACKGROUND" value="false" />
|
||||
<option name="CHECK_LOCALLY_CHANGED_CONFLICTS_IN_BACKGROUND" value="false" />
|
||||
<option name="CHANGED_ON_SERVER_INTERVAL" value="60" />
|
||||
<option name="SHOW_ONLY_CHANGED_IN_SELECTION_DIFF" value="true" />
|
||||
<option name="CHECK_COMMIT_MESSAGE_SPELLING" value="true" />
|
||||
<option name="DEFAULT_PATCH_EXTENSION" value="patch" />
|
||||
<option name="SHORT_DIFF_HORISONTALLY" value="true" />
|
||||
<option name="SHORT_DIFF_EXTRA_LINES" value="2" />
|
||||
<option name="SOFT_WRAPS_IN_SHORT_DIFF" value="true" />
|
||||
<option name="INCLUDE_TEXT_INTO_PATCH" value="false" />
|
||||
<option name="INCLUDE_TEXT_INTO_SHELF" value="false" />
|
||||
<option name="SHOW_FILE_HISTORY_DETAILS" value="true" />
|
||||
<option name="SHOW_VCS_ERROR_NOTIFICATIONS" value="true" />
|
||||
<option name="SHOW_DIRTY_RECURSIVELY" value="false" />
|
||||
<option name="LIMIT_HISTORY" value="true" />
|
||||
<option name="MAXIMUM_HISTORY_ROWS" value="1000" />
|
||||
<option name="FORCE_NON_EMPTY_COMMENT" value="false" />
|
||||
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="false" />
|
||||
<option name="LAST_COMMIT_MESSAGE" />
|
||||
<option name="MAKE_NEW_CHANGELIST_ACTIVE" value="false" />
|
||||
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
|
||||
<option name="CHECK_FILES_UP_TO_DATE_BEFORE_COMMIT" value="false" />
|
||||
<option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
|
||||
<option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
|
||||
<option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
|
||||
<option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
|
||||
<option name="ACTIVE_VCS_NAME" />
|
||||
<option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
|
||||
<option name="UPDATE_GROUP_BY_CHANGELIST" value="false" />
|
||||
<option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
|
||||
<option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/bootstrap/js/jquery-1.8.3.min.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
|
||||
<folding>
|
||||
<element signature="n#!!doc" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/index.html">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="24" column="96" selection-start="672" selection-end="672" vertical-scroll-proportion="-7.5">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/app.js">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state line="43" column="31" selection-start="1224" selection-end="1224" vertical-scroll-proportion="0.8895435">
|
||||
<folding />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
var express = require('express');
|
||||
var app = express();
|
||||
var server = require('http').createServer(app), io = require('socket.io').listen(server);
|
||||
var osc = require('node-osc');
|
||||
|
||||
var host = process.argv.length > 2 ? process.argv[2] : 'distinto.lp-server.net';
|
||||
var port = process.argv.length > 3 ? process.argv[3] : '5001';
|
||||
var oscSender = new osc.Client(host, port);
|
||||
|
||||
|
||||
var states = [];
|
||||
|
||||
server.listen(8080);
|
||||
app.use(express.static('bootstrap'));
|
||||
|
||||
app.get('/', function (req, res) {
|
||||
res.sendfile(__dirname + '/index.html');
|
||||
});
|
||||
|
||||
io.sockets.on('connection', function (socket) {
|
||||
//socket.emit('news', { hello: 'world' });
|
||||
|
||||
socket.on('oscmessage', function (data) {
|
||||
|
||||
var chan = data.chan;
|
||||
var value = data.val;
|
||||
|
||||
if(chan == null) return;
|
||||
|
||||
if(value == null) {
|
||||
if(states[chan] == null) {
|
||||
states[chan] = 1
|
||||
} else if(states[chan] == 1) {
|
||||
states[chan] = 0;
|
||||
} else if(states[chan] == 0) {
|
||||
states[chan] = 1;
|
||||
}
|
||||
value = states[chan];
|
||||
}
|
||||
|
||||
// hier noch nicht einkommentieren, das sendet das sofort ins hackcenter
|
||||
//oscSender.send(chan, value);
|
||||
|
||||
console.log(chan, value);
|
||||
});
|
||||
});
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bootstrap 101 Template</title>
|
||||
<!-- Bootstrap -->
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
|
||||
<style type="text/css">
|
||||
body { margin: 20px; }
|
||||
.kasten {
|
||||
display:block;
|
||||
background-color: green;
|
||||
width: 30%;
|
||||
height: 100px;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
<script src="js/jquery-1.8.3.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="span4 kasten" id="wabe1" data-channel="/2/multitoggle/1/1" data-value="1">
|
||||
</div>
|
||||
<div class="span4 kasten" id="wabe2" data-channel="/2/multitoggle/1/1" data-value="0">
|
||||
</div>
|
||||
<div class="span4 kasten" id="wabe3" data-channel="/2/multitoggle/1/2">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script>
|
||||
|
||||
|
||||
var socket = io.connect('http://localhost');
|
||||
socket.on('news', function (data) {
|
||||
console.log(data);
|
||||
//
|
||||
//handleDMXData(data);
|
||||
});
|
||||
|
||||
$(document).ready(function(evnt) {
|
||||
|
||||
$(document).delegate('.kasten', 'click', function(event) {
|
||||
var channel = $(this).data('channel');
|
||||
var value = $(this).data('value');
|
||||
if(channel != null) {
|
||||
|
||||
socket.emit('oscmessage', { chan: channel, val: value });
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
../express/bin/express
|
|
@ -0,0 +1 @@
|
|||
../nodemon/nodemon.js
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
module.exports = require('./lib/artnet-server.js');
|
|
@ -0,0 +1,31 @@
|
|||
var dgram = require('dgram');
|
||||
var Buffer = require('buffer').Buffer;
|
||||
|
||||
function ArtNetClient(host, port) {
|
||||
this._host = host;
|
||||
this._port = port;
|
||||
this.HEADER = [65, 114, 116, 45, 78, 101, 116, 0, 0, 80, 0, 14]; // 0 - 11
|
||||
this.SEQUENCE = [0]; // 12
|
||||
this.PHYSICAL = [0]; // 13
|
||||
this.UNIVERSE = [0, 0]; // 14 - 15
|
||||
//this.LENGTH = [0, 13]; // 16 - 17
|
||||
}
|
||||
exports.ArtNetClient = ArtNetClient;
|
||||
|
||||
exports.createClient = function(host, port) {
|
||||
return new ArtNetClient(host, port);
|
||||
}
|
||||
|
||||
ArtNetClient.prototype.send = function(data) {
|
||||
// Calcualte the length
|
||||
var length_upper = Math.floor(data.length / 256);
|
||||
var length_lower = data.length % 256;
|
||||
|
||||
var data = this.HEADER.concat(this.SEQUENCE).concat(this.PHYSICAL).concat(this.UNIVERSE).concat([length_upper, length_lower]).concat(data);
|
||||
var buf = Buffer(data);
|
||||
|
||||
var sock = dgram.createSocket("udp4");
|
||||
sock.send(buf, 0, buf.length, this._port, this._host, function() {
|
||||
sock.close();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
var util = require('util');
|
||||
var events = require('events');
|
||||
var dgram = require('dgram');
|
||||
|
||||
// ArtNet server class
|
||||
exports.listen = function(port, cb) {
|
||||
this.port = port;
|
||||
events.EventEmitter.call(this);
|
||||
|
||||
// Set up the socket
|
||||
var sock = dgram.createSocket("udp4", function (msg, peer) {
|
||||
var data = new Array();
|
||||
for (i = 0; i < msg.length; i++) {
|
||||
var d = msg.toString().charCodeAt(i);
|
||||
// Since we can't do unsigned 8-bit integers, do some normalization
|
||||
if (d < 0) {
|
||||
d = 0;
|
||||
} else if (d > 255) {
|
||||
d = 255;
|
||||
}
|
||||
|
||||
// Append the byte to the array
|
||||
data.push(d);
|
||||
}
|
||||
|
||||
// Deseralize the data - magic numbers are as per the Art-Net protocol
|
||||
var sequence = data[12];
|
||||
var physical = data[13];
|
||||
var universe = (data[14] * 256) + data[15];
|
||||
var length = (data[16] * 256) + data[17];
|
||||
|
||||
var rawData = new Array();
|
||||
for (i = 0; i < length; i++) {
|
||||
rawData.push(data[i + 18]);
|
||||
}
|
||||
|
||||
// Build the associative array to return
|
||||
var retData = {sequence: sequence, physical: physical, universe: universe, length: length, data: rawData};
|
||||
|
||||
// And call the callback passing the deseralized data
|
||||
cb(retData, peer);
|
||||
});
|
||||
sock.bind(port);
|
||||
}
|
||||
|
||||
// Setup EventEmitter for the ArtNetServer
|
||||
util.inherits(this, events.EventEmitter);
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "artnet",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"homepage": "",
|
||||
"author": {
|
||||
"name": "",
|
||||
"email": ""
|
||||
},
|
||||
"main": "index",
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
var artnetclient = require('../lib/artnet_client');
|
||||
|
||||
var data = [255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0];
|
||||
|
||||
var client = artnetclient.createClient('127.0.0.1', 6454);
|
||||
client.send(data);
|
|
@ -0,0 +1,11 @@
|
|||
var artnetsrv = require('../lib/artnet_server');
|
||||
|
||||
var srv = artnetsrv.listen(6454, function(msg, peer) {
|
||||
console.log("-----------------");
|
||||
console.log("Sequence: " + msg.sequence);
|
||||
console.log("Physical: " + msg.physical);
|
||||
console.log("Universe: " + msg.universe);
|
||||
console.log("Length: " + msg.length);
|
||||
console.log("Data: " + msg.data);
|
||||
console.log("-----------------");
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
.git*
|
||||
docs/
|
||||
examples/
|
||||
support/
|
||||
test/
|
||||
testing.js
|
||||
.DS_Store
|
||||
coverage.html
|
||||
lib-cov
|
|
@ -0,0 +1,3 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,22 @@
|
|||
(The MIT License)
|
||||
|
||||
Copyright (c) 2009-2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
MOCHA_OPTS=
|
||||
REPORTER = dot
|
||||
|
||||
check: test
|
||||
|
||||
test: test-unit test-acceptance
|
||||
|
||||
test-unit:
|
||||
@NODE_ENV=test ./node_modules/.bin/mocha \
|
||||
--reporter $(REPORTER) \
|
||||
$(MOCHA_OPTS)
|
||||
|
||||
test-acceptance:
|
||||
@NODE_ENV=test ./node_modules/.bin/mocha \
|
||||
--reporter $(REPORTER) \
|
||||
--bail \
|
||||
test/acceptance/*.js
|
||||
|
||||
test-cov: lib-cov
|
||||
@EXPRESS_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html
|
||||
|
||||
lib-cov:
|
||||
@jscoverage lib lib-cov
|
||||
|
||||
benchmark:
|
||||
@./support/bench
|
||||
|
||||
clean:
|
||||
rm -f coverage.html
|
||||
rm -fr lib-cov
|
||||
|
||||
.PHONY: test test-unit test-acceptance benchmark clean
|
|
@ -0,0 +1,179 @@
|
|||
![express logo](http://f.cl.ly/items/0V2S1n0K1i3y1c122g04/Screen%20Shot%202012-04-11%20at%209.59.42%20AM.png)
|
||||
|
||||
Fast, unopinionated, minimalist web framework for [node](http://nodejs.org). [![Build Status](https://secure.travis-ci.org/visionmedia/express.png)](http://travis-ci.org/visionmedia/express)
|
||||
|
||||
```js
|
||||
var express = require('express');
|
||||
var app = express();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('Hello World');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
$ npm install -g express
|
||||
|
||||
## Quick Start
|
||||
|
||||
The quickest way to get started with express is to utilize the executable `express(1)` to generate an application as shown below:
|
||||
|
||||
Create the app:
|
||||
|
||||
$ npm install -g express
|
||||
$ express /tmp/foo && cd /tmp/foo
|
||||
|
||||
Install dependencies:
|
||||
|
||||
$ npm install
|
||||
|
||||
Start the server:
|
||||
|
||||
$ node app
|
||||
|
||||
## Features
|
||||
|
||||
* Built on [Connect](http://github.com/senchalabs/connect)
|
||||
* Robust routing
|
||||
* HTTP helpers (redirection, caching, etc)
|
||||
* View system supporting 14+ template engines
|
||||
* Content negotiation
|
||||
* Focus on high performance
|
||||
* Environment based configuration
|
||||
* Executable for generating applications quickly
|
||||
* High test coverage
|
||||
|
||||
## Philosophy
|
||||
|
||||
The Express philosophy is to provide small, robust tooling for HTTP servers. Making
|
||||
it a great solution for single page applications, web sites, hybrids, or public
|
||||
HTTP APIs.
|
||||
|
||||
Built on Connect you can use _only_ what you need, and nothing more, applications
|
||||
can be as big or as small as you like, even a single file. Express does
|
||||
not force you to use any specific ORM or template engine. With support for over
|
||||
14 template engines via [Consolidate.js](http://github.com/visionmedia/consolidate.js)
|
||||
you can quickly craft your perfect framework.
|
||||
|
||||
## More Information
|
||||
|
||||
* Join #express on freenode
|
||||
* [Google Group](http://groups.google.com/group/express-js) for discussion
|
||||
* Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates
|
||||
* Visit the [Wiki](http://github.com/visionmedia/express/wiki)
|
||||
* [日本語ドキュメンテーション](http://hideyukisaito.com/doc/expressjs/) by [hideyukisaito](https://github.com/hideyukisaito)
|
||||
* [Русскоязычная документация](http://express-js.ru/)
|
||||
|
||||
## Viewing Examples
|
||||
|
||||
Clone the Express repo, then install the dev dependencies to install all the example / test suite deps:
|
||||
|
||||
$ git clone git://github.com/visionmedia/express.git --depth 1
|
||||
$ cd express
|
||||
$ npm install
|
||||
|
||||
then run whichever tests you want:
|
||||
|
||||
$ node examples/content-negotiation
|
||||
|
||||
## Running Tests
|
||||
|
||||
To run the test suite first invoke the following command within the repo, installing the development dependencies:
|
||||
|
||||
$ npm install
|
||||
|
||||
then run the tests:
|
||||
|
||||
$ make test
|
||||
|
||||
## Contributors
|
||||
|
||||
```
|
||||
project: express
|
||||
commits: 3559
|
||||
active : 468 days
|
||||
files : 237
|
||||
authors:
|
||||
1891 Tj Holowaychuk 53.1%
|
||||
1285 visionmedia 36.1%
|
||||
182 TJ Holowaychuk 5.1%
|
||||
54 Aaron Heckmann 1.5%
|
||||
34 csausdev 1.0%
|
||||
26 ciaranj 0.7%
|
||||
21 Robert Sköld 0.6%
|
||||
6 Guillermo Rauch 0.2%
|
||||
3 Dav Glass 0.1%
|
||||
3 Nick Poulden 0.1%
|
||||
2 Randy Merrill 0.1%
|
||||
2 Benny Wong 0.1%
|
||||
2 Hunter Loftis 0.1%
|
||||
2 Jake Gordon 0.1%
|
||||
2 Brian McKinney 0.1%
|
||||
2 Roman Shtylman 0.1%
|
||||
2 Ben Weaver 0.1%
|
||||
2 Dave Hoover 0.1%
|
||||
2 Eivind Fjeldstad 0.1%
|
||||
2 Daniel Shaw 0.1%
|
||||
1 Matt Colyer 0.0%
|
||||
1 Pau Ramon 0.0%
|
||||
1 Pero Pejovic 0.0%
|
||||
1 Peter Rekdal Sunde 0.0%
|
||||
1 Raynos 0.0%
|
||||
1 Teng Siong Ong 0.0%
|
||||
1 Viktor Kelemen 0.0%
|
||||
1 ctide 0.0%
|
||||
1 8bitDesigner 0.0%
|
||||
1 isaacs 0.0%
|
||||
1 mgutz 0.0%
|
||||
1 pikeas 0.0%
|
||||
1 shuwatto 0.0%
|
||||
1 tstrimple 0.0%
|
||||
1 ewoudj 0.0%
|
||||
1 Adam Sanderson 0.0%
|
||||
1 Andrii Kostenko 0.0%
|
||||
1 Andy Hiew 0.0%
|
||||
1 Arpad Borsos 0.0%
|
||||
1 Ashwin Purohit 0.0%
|
||||
1 Benjen 0.0%
|
||||
1 Darren Torpey 0.0%
|
||||
1 Greg Ritter 0.0%
|
||||
1 Gregory Ritter 0.0%
|
||||
1 James Herdman 0.0%
|
||||
1 Jim Snodgrass 0.0%
|
||||
1 Joe McCann 0.0%
|
||||
1 Jonathan Dumaine 0.0%
|
||||
1 Jonathan Palardy 0.0%
|
||||
1 Jonathan Zacsh 0.0%
|
||||
1 Justin Lilly 0.0%
|
||||
1 Ken Sato 0.0%
|
||||
1 Maciej Małecki 0.0%
|
||||
1 Masahiro Hayashi 0.0%
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2009-2012 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,422 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var exec = require('child_process').exec
|
||||
, program = require('commander')
|
||||
, mkdirp = require('mkdirp')
|
||||
, pkg = require('../package.json')
|
||||
, version = pkg.version
|
||||
, os = require('os')
|
||||
, fs = require('fs');
|
||||
|
||||
// CLI
|
||||
|
||||
program
|
||||
.version(version)
|
||||
.option('-s, --sessions', 'add session support')
|
||||
.option('-e, --ejs', 'add ejs engine support (defaults to jade)')
|
||||
.option('-J, --jshtml', 'add jshtml engine support (defaults to jade)')
|
||||
.option('-H, --hogan', 'add hogan.js engine support')
|
||||
.option('-c, --css <engine>', 'add stylesheet <engine> support (less|stylus) (defaults to plain css)')
|
||||
.option('-f, --force', 'force on non-empty directory')
|
||||
.parse(process.argv);
|
||||
|
||||
// Path
|
||||
|
||||
var path = program.args.shift() || '.';
|
||||
|
||||
// end-of-line code
|
||||
|
||||
var eol = 'win32' == os.platform() ? '\r\n' : '\n'
|
||||
|
||||
// Template engine
|
||||
|
||||
program.template = 'jade';
|
||||
if (program.ejs) program.template = 'ejs';
|
||||
if (program.jshtml) program.template = 'jshtml';
|
||||
if (program.hogan) program.template = 'hjs';
|
||||
|
||||
/**
|
||||
* Routes index template.
|
||||
*/
|
||||
|
||||
var index = [
|
||||
''
|
||||
, '/*'
|
||||
, ' * GET home page.'
|
||||
, ' */'
|
||||
, ''
|
||||
, 'exports.index = function(req, res){'
|
||||
, ' res.render(\'index\', { title: \'Express\' });'
|
||||
, '};'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Routes users template.
|
||||
*/
|
||||
|
||||
var users = [
|
||||
''
|
||||
, '/*'
|
||||
, ' * GET users listing.'
|
||||
, ' */'
|
||||
, ''
|
||||
, 'exports.list = function(req, res){'
|
||||
, ' res.send("respond with a resource");'
|
||||
, '};'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Jade layout template.
|
||||
*/
|
||||
|
||||
var jadeLayout = [
|
||||
'doctype 5'
|
||||
, 'html'
|
||||
, ' head'
|
||||
, ' title= title'
|
||||
, ' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')'
|
||||
, ' body'
|
||||
, ' block content'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Jade index template.
|
||||
*/
|
||||
|
||||
var jadeIndex = [
|
||||
'extends layout'
|
||||
, ''
|
||||
, 'block content'
|
||||
, ' h1= title'
|
||||
, ' p Welcome to #{title}'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* EJS index template.
|
||||
*/
|
||||
|
||||
var ejsIndex = [
|
||||
'<!DOCTYPE html>'
|
||||
, '<html>'
|
||||
, ' <head>'
|
||||
, ' <title><%= title %></title>'
|
||||
, ' <link rel=\'stylesheet\' href=\'/stylesheets/style.css\' />'
|
||||
, ' </head>'
|
||||
, ' <body>'
|
||||
, ' <h1><%= title %></h1>'
|
||||
, ' <p>Welcome to <%= title %></p>'
|
||||
, ' </body>'
|
||||
, '</html>'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* JSHTML layout template.
|
||||
*/
|
||||
|
||||
var jshtmlLayout = [
|
||||
'<!DOCTYPE html>'
|
||||
, '<html>'
|
||||
, ' <head>'
|
||||
, ' <title> @write(title) </title>'
|
||||
, ' <link rel=\'stylesheet\' href=\'/stylesheets/style.css\' />'
|
||||
, ' </head>'
|
||||
, ' <body>'
|
||||
, ' @write(body)'
|
||||
, ' </body>'
|
||||
, '</html>'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* JSHTML index template.
|
||||
*/
|
||||
|
||||
var jshtmlIndex = [
|
||||
'<h1>@write(title)</h1>'
|
||||
, '<p>Welcome to @write(title)</p>'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Hogan.js index template.
|
||||
*/
|
||||
var hoganIndex = [
|
||||
'<!DOCTYPE html>'
|
||||
, '<html>'
|
||||
, ' <head>'
|
||||
, ' <title>{{ title }}</title>'
|
||||
, ' <link rel=\'stylesheet\' href=\'/stylesheets/style.css\' />'
|
||||
, ' </head>'
|
||||
, ' <body>'
|
||||
, ' <h1>{{ title }}</h1>'
|
||||
, ' <p>Welcome to {{ title }}</p>'
|
||||
, ' </body>'
|
||||
, '</html>'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Default css template.
|
||||
*/
|
||||
|
||||
var css = [
|
||||
'body {'
|
||||
, ' padding: 50px;'
|
||||
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;'
|
||||
, '}'
|
||||
, ''
|
||||
, 'a {'
|
||||
, ' color: #00B7FF;'
|
||||
, '}'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Default less template.
|
||||
*/
|
||||
|
||||
var less = [
|
||||
'body {'
|
||||
, ' padding: 50px;'
|
||||
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;'
|
||||
, '}'
|
||||
, ''
|
||||
, 'a {'
|
||||
, ' color: #00B7FF;'
|
||||
, '}'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Default stylus template.
|
||||
*/
|
||||
|
||||
var stylus = [
|
||||
'body'
|
||||
, ' padding: 50px'
|
||||
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif'
|
||||
, 'a'
|
||||
, ' color: #00B7FF'
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* App template.
|
||||
*/
|
||||
|
||||
var app = [
|
||||
''
|
||||
, '/**'
|
||||
, ' * Module dependencies.'
|
||||
, ' */'
|
||||
, ''
|
||||
, 'var express = require(\'express\')'
|
||||
, ' , routes = require(\'./routes\')'
|
||||
, ' , user = require(\'./routes/user\')'
|
||||
, ' , http = require(\'http\')'
|
||||
, ' , path = require(\'path\');'
|
||||
, ''
|
||||
, 'var app = express();'
|
||||
, ''
|
||||
, 'app.configure(function(){'
|
||||
, ' app.set(\'port\', process.env.PORT || 3000);'
|
||||
, ' app.set(\'views\', __dirname + \'/views\');'
|
||||
, ' app.set(\'view engine\', \':TEMPLATE\');'
|
||||
, ' app.use(express.favicon());'
|
||||
, ' app.use(express.logger(\'dev\'));'
|
||||
, ' app.use(express.bodyParser());'
|
||||
, ' app.use(express.methodOverride());{sess}'
|
||||
, ' app.use(app.router);{css}'
|
||||
, ' app.use(express.static(path.join(__dirname, \'public\')));'
|
||||
, '});'
|
||||
, ''
|
||||
, 'app.configure(\'development\', function(){'
|
||||
, ' app.use(express.errorHandler());'
|
||||
, '});'
|
||||
, ''
|
||||
, 'app.get(\'/\', routes.index);'
|
||||
, 'app.get(\'/users\', user.list);'
|
||||
, ''
|
||||
, 'http.createServer(app).listen(app.get(\'port\'), function(){'
|
||||
, ' console.log("Express server listening on port " + app.get(\'port\'));'
|
||||
, '});'
|
||||
, ''
|
||||
].join(eol);
|
||||
|
||||
// Generate application
|
||||
|
||||
(function createApplication(path) {
|
||||
emptyDirectory(path, function(empty){
|
||||
if (empty || program.force) {
|
||||
createApplicationAt(path);
|
||||
} else {
|
||||
program.confirm('destination is not empty, continue? ', function(ok){
|
||||
if (ok) {
|
||||
process.stdin.destroy();
|
||||
createApplicationAt(path);
|
||||
} else {
|
||||
abort('aborting');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})(path);
|
||||
|
||||
/**
|
||||
* Create application at the given directory `path`.
|
||||
*
|
||||
* @param {String} path
|
||||
*/
|
||||
|
||||
function createApplicationAt(path) {
|
||||
console.log();
|
||||
process.on('exit', function(){
|
||||
console.log();
|
||||
console.log(' install dependencies:');
|
||||
console.log(' $ cd %s && npm install', path);
|
||||
console.log();
|
||||
console.log(' run the app:');
|
||||
console.log(' $ node app');
|
||||
console.log();
|
||||
});
|
||||
|
||||
mkdir(path, function(){
|
||||
mkdir(path + '/public');
|
||||
mkdir(path + '/public/javascripts');
|
||||
mkdir(path + '/public/images');
|
||||
mkdir(path + '/public/stylesheets', function(){
|
||||
switch (program.css) {
|
||||
case 'less':
|
||||
write(path + '/public/stylesheets/style.less', less);
|
||||
break;
|
||||
case 'stylus':
|
||||
write(path + '/public/stylesheets/style.styl', stylus);
|
||||
break;
|
||||
default:
|
||||
write(path + '/public/stylesheets/style.css', css);
|
||||
}
|
||||
});
|
||||
|
||||
mkdir(path + '/routes', function(){
|
||||
write(path + '/routes/index.js', index);
|
||||
write(path + '/routes/user.js', users);
|
||||
});
|
||||
|
||||
mkdir(path + '/views', function(){
|
||||
switch (program.template) {
|
||||
case 'ejs':
|
||||
write(path + '/views/index.ejs', ejsIndex);
|
||||
break;
|
||||
case 'jade':
|
||||
write(path + '/views/layout.jade', jadeLayout);
|
||||
write(path + '/views/index.jade', jadeIndex);
|
||||
break;
|
||||
case 'jshtml':
|
||||
write(path + '/views/layout.jshtml', jshtmlLayout);
|
||||
write(path + '/views/index.jshtml', jshtmlIndex);
|
||||
break;
|
||||
case 'hjs':
|
||||
write(path + '/views/index.hjs', hoganIndex);
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// CSS Engine support
|
||||
switch (program.css) {
|
||||
case 'less':
|
||||
app = app.replace('{css}', eol + ' app.use(require(\'less-middleware\')({ src: __dirname + \'/public\' }));');
|
||||
break;
|
||||
case 'stylus':
|
||||
app = app.replace('{css}', eol + ' app.use(require(\'stylus\').middleware(__dirname + \'/public\'));');
|
||||
break;
|
||||
default:
|
||||
app = app.replace('{css}', '');
|
||||
}
|
||||
|
||||
// Session support
|
||||
app = app.replace('{sess}', program.sessions
|
||||
? eol + ' app.use(express.cookieParser(\'your secret here\'));' + eol + ' app.use(express.session());'
|
||||
: '');
|
||||
|
||||
// Template support
|
||||
app = app.replace(':TEMPLATE', program.template);
|
||||
|
||||
// package.json
|
||||
var pkg = {
|
||||
name: 'application-name'
|
||||
, version: '0.0.1'
|
||||
, private: true
|
||||
, scripts: { start: 'node app' }
|
||||
, dependencies: {
|
||||
express: version
|
||||
}
|
||||
}
|
||||
|
||||
if (program.template) pkg.dependencies[program.template] = '*';
|
||||
|
||||
// CSS Engine support
|
||||
switch (program.css) {
|
||||
case 'less':
|
||||
pkg.dependencies['less-middleware'] = '*';
|
||||
break;
|
||||
default:
|
||||
if (program.css) {
|
||||
pkg.dependencies[program.css] = '*';
|
||||
}
|
||||
}
|
||||
|
||||
write(path + '/package.json', JSON.stringify(pkg, null, 2));
|
||||
write(path + '/app.js', app);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given directory `path` is empty.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} fn
|
||||
*/
|
||||
|
||||
function emptyDirectory(path, fn) {
|
||||
fs.readdir(path, function(err, files){
|
||||
if (err && 'ENOENT' != err.code) throw err;
|
||||
fn(!files || !files.length);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* echo str > path.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {String} str
|
||||
*/
|
||||
|
||||
function write(path, str) {
|
||||
fs.writeFile(path, str);
|
||||
console.log(' \x1b[36mcreate\x1b[0m : ' + path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mkdir -p.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} fn
|
||||
*/
|
||||
|
||||
function mkdir(path, fn) {
|
||||
mkdirp(path, 0755, function(err){
|
||||
if (err) throw err;
|
||||
console.log(' \033[36mcreate\033[0m : ' + path);
|
||||
fn && fn();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit with the given `str`.
|
||||
*
|
||||
* @param {String} str
|
||||
*/
|
||||
|
||||
function abort(str) {
|
||||
console.error(str);
|
||||
process.exit(1);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
var http = require('http');
|
||||
|
||||
var times = 50;
|
||||
|
||||
while (times--) {
|
||||
var req = http.request({
|
||||
port: 3000
|
||||
, method: 'POST'
|
||||
, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
|
||||
});
|
||||
|
||||
req.on('response', function(res){
|
||||
console.log(res.statusCode);
|
||||
});
|
||||
|
||||
var n = 500000;
|
||||
while (n--) {
|
||||
req.write('foo=bar&bar=baz&');
|
||||
}
|
||||
|
||||
req.write('foo=bar&bar=baz');
|
||||
|
||||
req.end();
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
module.exports = process.env.EXPRESS_COV
|
||||
? require('./lib-cov/express')
|
||||
: require('./lib/express');
|
|
@ -0,0 +1,531 @@
|
|||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var connect = require('connect')
|
||||
, Router = require('./router')
|
||||
, methods = require('methods')
|
||||
, middleware = require('./middleware')
|
||||
, debug = require('debug')('express:application')
|
||||
, locals = require('./utils').locals
|
||||
, View = require('./view')
|
||||
, utils = connect.utils
|
||||
, path = require('path')
|
||||
, http = require('http')
|
||||
, join = path.join;
|
||||
|
||||
/**
|
||||
* Application prototype.
|
||||
*/
|
||||
|
||||
var app = exports = module.exports = {};
|
||||
|
||||
/**
|
||||
* Initialize the server.
|
||||
*
|
||||
* - setup default configuration
|
||||
* - setup default middleware
|
||||
* - setup route reflection methods
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
app.init = function(){
|
||||
this.cache = {};
|
||||
this.settings = {};
|
||||
this.engines = {};
|
||||
this.viewCallbacks = [];
|
||||
this.defaultConfiguration();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize application configuration.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
app.defaultConfiguration = function(){
|
||||
// default settings
|
||||
this.enable('x-powered-by');
|
||||
this.enable('etag');
|
||||
this.set('env', process.env.NODE_ENV || 'development');
|
||||
debug('booting in %s mode', this.get('env'));
|
||||
|
||||
// implicit middleware
|
||||
this.use(connect.query());
|
||||
this.use(middleware.init(this));
|
||||
|
||||
// inherit protos
|
||||
this.on('mount', function(parent){
|
||||
this.request.__proto__ = parent.request;
|
||||
this.response.__proto__ = parent.response;
|
||||
this.engines.__proto__ = parent.engines;
|
||||
});
|
||||
|
||||
// router
|
||||
this._router = new Router(this);
|
||||
this.routes = this._router.map;
|
||||
this.__defineGetter__('router', function(){
|
||||
this._usedRouter = true;
|
||||
this._router.caseSensitive = this.enabled('case sensitive routing');
|
||||
this._router.strict = this.enabled('strict routing');
|
||||
return this._router.middleware;
|
||||
});
|
||||
|
||||
// setup locals
|
||||
this.locals = locals(this);
|
||||
|
||||
// default locals
|
||||
this.locals.settings = this.settings;
|
||||
|
||||
// default configuration
|
||||
this.set('views', process.cwd() + '/views');
|
||||
this.set('jsonp callback name', 'callback');
|
||||
|
||||
this.configure('development', function(){
|
||||
this.set('json spaces', 2);
|
||||
});
|
||||
|
||||
this.configure('production', function(){
|
||||
this.enable('view cache');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Proxy `connect#use()` to apply settings to
|
||||
* mounted applications.
|
||||
*
|
||||
* @param {String|Function|Server} route
|
||||
* @param {Function|Server} fn
|
||||
* @return {app} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.use = function(route, fn){
|
||||
var app;
|
||||
|
||||
// default route to '/'
|
||||
if ('string' != typeof route) fn = route, route = '/';
|
||||
|
||||
// express app
|
||||
if (fn.handle && fn.set) app = fn;
|
||||
|
||||
// restore .app property on req and res
|
||||
if (app) {
|
||||
app.route = route;
|
||||
fn = function(req, res, next) {
|
||||
var orig = req.app;
|
||||
app.handle(req, res, function(err){
|
||||
req.app = res.app = orig;
|
||||
req.__proto__ = orig.request;
|
||||
res.__proto__ = orig.response;
|
||||
next(err);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
connect.proto.use.call(this, route, fn);
|
||||
|
||||
// mounted an app
|
||||
if (app) {
|
||||
app.parent = this;
|
||||
app.emit('mount', this);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register the given template engine callback `fn`
|
||||
* as `ext`.
|
||||
*
|
||||
* By default will `require()` the engine based on the
|
||||
* file extension. For example if you try to render
|
||||
* a "foo.jade" file Express will invoke the following internally:
|
||||
*
|
||||
* app.engine('jade', require('jade').__express);
|
||||
*
|
||||
* For engines that do not provide `.__express` out of the box,
|
||||
* or if you wish to "map" a different extension to the template engine
|
||||
* you may use this method. For example mapping the EJS template engine to
|
||||
* ".html" files:
|
||||
*
|
||||
* app.engine('html', require('ejs').renderFile);
|
||||
*
|
||||
* In this case EJS provides a `.renderFile()` method with
|
||||
* the same signature that Express expects: `(path, options, callback)`,
|
||||
* though note that it aliases this method as `ejs.__express` internally
|
||||
* so if you're using ".ejs" extensions you dont need to do anything.
|
||||
*
|
||||
* Some template engines do not follow this convention, the
|
||||
* [Consolidate.js](https://github.com/visionmedia/consolidate.js)
|
||||
* library was created to map all of node's popular template
|
||||
* engines to follow this convention, thus allowing them to
|
||||
* work seemlessly within Express.
|
||||
*
|
||||
* @param {String} ext
|
||||
* @param {Function} fn
|
||||
* @return {app} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.engine = function(ext, fn){
|
||||
if ('function' != typeof fn) throw new Error('callback function required');
|
||||
if ('.' != ext[0]) ext = '.' + ext;
|
||||
this.engines[ext] = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Map the given param placeholder `name`(s) to the given callback(s).
|
||||
*
|
||||
* Parameter mapping is used to provide pre-conditions to routes
|
||||
* which use normalized placeholders. For example a _:user_id_ parameter
|
||||
* could automatically load a user's information from the database without
|
||||
* any additional code,
|
||||
*
|
||||
* The callback uses the samesignature as middleware, the only differencing
|
||||
* being that the value of the placeholder is passed, in this case the _id_
|
||||
* of the user. Once the `next()` function is invoked, just like middleware
|
||||
* it will continue on to execute the route, or subsequent parameter functions.
|
||||
*
|
||||
* app.param('user_id', function(req, res, next, id){
|
||||
* User.find(id, function(err, user){
|
||||
* if (err) {
|
||||
* next(err);
|
||||
* } else if (user) {
|
||||
* req.user = user;
|
||||
* next();
|
||||
* } else {
|
||||
* next(new Error('failed to load user'));
|
||||
* }
|
||||
* });
|
||||
* });
|
||||
*
|
||||
* @param {String|Array} name
|
||||
* @param {Function} fn
|
||||
* @return {app} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.param = function(name, fn){
|
||||
var self = this
|
||||
, fns = [].slice.call(arguments, 1);
|
||||
|
||||
// array
|
||||
if (Array.isArray(name)) {
|
||||
name.forEach(function(name){
|
||||
fns.forEach(function(fn){
|
||||
self.param(name, fn);
|
||||
});
|
||||
});
|
||||
// param logic
|
||||
} else if ('function' == typeof name) {
|
||||
this._router.param(name);
|
||||
// single
|
||||
} else {
|
||||
if (':' == name[0]) name = name.substr(1);
|
||||
fns.forEach(function(fn){
|
||||
self._router.param(name, fn);
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Assign `setting` to `val`, or return `setting`'s value.
|
||||
*
|
||||
* app.set('foo', 'bar');
|
||||
* app.get('foo');
|
||||
* // => "bar"
|
||||
*
|
||||
* Mounted servers inherit their parent server's settings.
|
||||
*
|
||||
* @param {String} setting
|
||||
* @param {String} val
|
||||
* @return {Server} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.set = function(setting, val){
|
||||
if (1 == arguments.length) {
|
||||
if (this.settings.hasOwnProperty(setting)) {
|
||||
return this.settings[setting];
|
||||
} else if (this.parent) {
|
||||
return this.parent.set(setting);
|
||||
}
|
||||
} else {
|
||||
this.settings[setting] = val;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the app's absolute pathname
|
||||
* based on the parent(s) that have
|
||||
* mounted it.
|
||||
*
|
||||
* For example if the application was
|
||||
* mounted as "/admin", which itself
|
||||
* was mounted as "/blog" then the
|
||||
* return value would be "/blog/admin".
|
||||
*
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
app.path = function(){
|
||||
return this.parent
|
||||
? this.parent.path() + this.route
|
||||
: '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if `setting` is enabled (truthy).
|
||||
*
|
||||
* app.enabled('foo')
|
||||
* // => false
|
||||
*
|
||||
* app.enable('foo')
|
||||
* app.enabled('foo')
|
||||
* // => true
|
||||
*
|
||||
* @param {String} setting
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.enabled = function(setting){
|
||||
return !!this.set(setting);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if `setting` is disabled.
|
||||
*
|
||||
* app.disabled('foo')
|
||||
* // => true
|
||||
*
|
||||
* app.enable('foo')
|
||||
* app.disabled('foo')
|
||||
* // => false
|
||||
*
|
||||
* @param {String} setting
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.disabled = function(setting){
|
||||
return !this.set(setting);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable `setting`.
|
||||
*
|
||||
* @param {String} setting
|
||||
* @return {app} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.enable = function(setting){
|
||||
return this.set(setting, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable `setting`.
|
||||
*
|
||||
* @param {String} setting
|
||||
* @return {app} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.disable = function(setting){
|
||||
return this.set(setting, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure callback for zero or more envs,
|
||||
* when no `env` is specified that callback will
|
||||
* be invoked for all environments. Any combination
|
||||
* can be used multiple times, in any order desired.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* app.configure(function(){
|
||||
* // executed for all envs
|
||||
* });
|
||||
*
|
||||
* app.configure('stage', function(){
|
||||
* // executed staging env
|
||||
* });
|
||||
*
|
||||
* app.configure('stage', 'production', function(){
|
||||
* // executed for stage and production
|
||||
* });
|
||||
*
|
||||
* Note:
|
||||
*
|
||||
* These callbacks are invoked immediately, and
|
||||
* are effectively sugar for the following:
|
||||
*
|
||||
* var env = process.env.NODE_ENV || 'development';
|
||||
*
|
||||
* switch (env) {
|
||||
* case 'development':
|
||||
* ...
|
||||
* break;
|
||||
* case 'stage':
|
||||
* ...
|
||||
* break;
|
||||
* case 'production':
|
||||
* ...
|
||||
* break;
|
||||
* }
|
||||
*
|
||||
* @param {String} env...
|
||||
* @param {Function} fn
|
||||
* @return {app} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.configure = function(env, fn){
|
||||
var envs = 'all'
|
||||
, args = [].slice.call(arguments);
|
||||
fn = args.pop();
|
||||
if (args.length) envs = args;
|
||||
if ('all' == envs || ~envs.indexOf(this.settings.env)) fn.call(this);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delegate `.VERB(...)` calls to `.route(VERB, ...)`.
|
||||
*/
|
||||
|
||||
methods.forEach(function(method){
|
||||
app[method] = function(path){
|
||||
if ('get' == method && 1 == arguments.length) return this.set(path);
|
||||
var args = [method].concat([].slice.call(arguments));
|
||||
if (!this._usedRouter) this.use(this.router);
|
||||
this._router.route.apply(this._router, args);
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Special-cased "all" method, applying the given route `path`,
|
||||
* middleware, and callback to _every_ HTTP method.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} ...
|
||||
* @return {app} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.all = function(path){
|
||||
var args = arguments;
|
||||
methods.forEach(function(method){
|
||||
app[method].apply(this, args);
|
||||
}, this);
|
||||
return this;
|
||||
};
|
||||
|
||||
// del -> delete alias
|
||||
|
||||
app.del = app.delete;
|
||||
|
||||
/**
|
||||
* Render the given view `name` name with `options`
|
||||
* and a callback accepting an error and the
|
||||
* rendered template string.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* app.render('email', { name: 'Tobi' }, function(err, html){
|
||||
* // ...
|
||||
* })
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String|Function} options or fn
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.render = function(name, options, fn){
|
||||
var opts = {}
|
||||
, cache = this.cache
|
||||
, engines = this.engines
|
||||
, view;
|
||||
|
||||
// support callback function as second arg
|
||||
if ('function' == typeof options) {
|
||||
fn = options, options = {};
|
||||
}
|
||||
|
||||
// merge app.locals
|
||||
utils.merge(opts, this.locals);
|
||||
|
||||
// merge options._locals
|
||||
if (options._locals) utils.merge(opts, options._locals);
|
||||
|
||||
// merge options
|
||||
utils.merge(opts, options);
|
||||
|
||||
// set .cache unless explicitly provided
|
||||
opts.cache = null == opts.cache
|
||||
? this.enabled('view cache')
|
||||
: opts.cache;
|
||||
|
||||
// primed cache
|
||||
if (opts.cache) view = cache[name];
|
||||
|
||||
// view
|
||||
if (!view) {
|
||||
view = new View(name, {
|
||||
defaultEngine: this.get('view engine'),
|
||||
root: this.get('views'),
|
||||
engines: engines
|
||||
});
|
||||
|
||||
if (!view.path) {
|
||||
var err = new Error('Failed to lookup view "' + name + '"');
|
||||
err.view = view;
|
||||
return fn(err);
|
||||
}
|
||||
|
||||
// prime the cache
|
||||
if (opts.cache) cache[name] = view;
|
||||
}
|
||||
|
||||
// render
|
||||
try {
|
||||
view.render(opts, fn);
|
||||
} catch (err) {
|
||||
fn(err);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen for connections.
|
||||
*
|
||||
* A node `http.Server` is returned, with this
|
||||
* application (which is a `Function`) as its
|
||||
* callback. If you wish to create both an HTTP
|
||||
* and HTTPS server you may do so with the "http"
|
||||
* and "https" modules as shown here:
|
||||
*
|
||||
* var http = require('http')
|
||||
* , https = require('https')
|
||||
* , express = require('express')
|
||||
* , app = express();
|
||||
*
|
||||
* http.createServer(app).listen(80);
|
||||
* https.createServer({ ... }, app).listen(443);
|
||||
*
|
||||
* @return {http.Server}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.listen = function(){
|
||||
var server = http.createServer(this);
|
||||
return server.listen.apply(server, arguments);
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var connect = require('connect')
|
||||
, proto = require('./application')
|
||||
, Route = require('./router/route')
|
||||
, Router = require('./router')
|
||||
, req = require('./request')
|
||||
, res = require('./response')
|
||||
, utils = connect.utils;
|
||||
|
||||
/**
|
||||
* Expose `createApplication()`.
|
||||
*/
|
||||
|
||||
exports = module.exports = createApplication;
|
||||
|
||||
/**
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
exports.version = '3.0.3';
|
||||
|
||||
/**
|
||||
* Expose mime.
|
||||
*/
|
||||
|
||||
exports.mime = connect.mime;
|
||||
|
||||
/**
|
||||
* Create an express application.
|
||||
*
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function createApplication() {
|
||||
var app = connect();
|
||||
utils.merge(app, proto);
|
||||
app.request = { __proto__: req };
|
||||
app.response = { __proto__: res };
|
||||
app.init();
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose connect.middleware as express.*
|
||||
* for example `express.logger` etc.
|
||||
*/
|
||||
|
||||
for (var key in connect.middleware) {
|
||||
Object.defineProperty(
|
||||
exports
|
||||
, key
|
||||
, Object.getOwnPropertyDescriptor(connect.middleware, key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Error on createServer().
|
||||
*/
|
||||
|
||||
exports.createServer = function(){
|
||||
console.warn('Warning: express.createServer() is deprecated, express');
|
||||
console.warn('applications no longer inherit from http.Server,');
|
||||
console.warn('please use:');
|
||||
console.warn('');
|
||||
console.warn(' var express = require("express");');
|
||||
console.warn(' var app = express();');
|
||||
console.warn('');
|
||||
return createApplication();
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose the prototypes.
|
||||
*/
|
||||
|
||||
exports.application = proto;
|
||||
exports.request = req;
|
||||
exports.response = res;
|
||||
|
||||
/**
|
||||
* Expose constructors.
|
||||
*/
|
||||
|
||||
exports.Route = Route;
|
||||
exports.Router = Router;
|
||||
|
||||
// Error handler title
|
||||
|
||||
exports.errorHandler.title = 'Express';
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('./utils');
|
||||
|
||||
/**
|
||||
* Initialization middleware, exposing the
|
||||
* request and response to eachother, as well
|
||||
* as defaulting the X-Powered-By header field.
|
||||
*
|
||||
* @param {Function} app
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.init = function(app){
|
||||
return function expressInit(req, res, next){
|
||||
req.app = res.app = app;
|
||||
if (app.settings['x-powered-by']) res.setHeader('X-Powered-By', 'Express');
|
||||
req.res = res;
|
||||
res.req = req;
|
||||
req.next = next;
|
||||
|
||||
req.__proto__ = app.request;
|
||||
res.__proto__ = app.response;
|
||||
|
||||
res.locals = res.locals || utils.locals(res);
|
||||
|
||||
next();
|
||||
}
|
||||
};
|
|
@ -0,0 +1,486 @@
|
|||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http')
|
||||
, utils = require('./utils')
|
||||
, connect = require('connect')
|
||||
, fresh = require('fresh')
|
||||
, parseRange = require('range-parser')
|
||||
, parse = connect.utils.parseUrl
|
||||
, mime = connect.mime;
|
||||
|
||||
/**
|
||||
* Request prototype.
|
||||
*/
|
||||
|
||||
var req = exports = module.exports = {
|
||||
__proto__: http.IncomingMessage.prototype
|
||||
};
|
||||
|
||||
/**
|
||||
* Return request header.
|
||||
*
|
||||
* The `Referrer` header field is special-cased,
|
||||
* both `Referrer` and `Referer` are interchangeable.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* req.get('Content-Type');
|
||||
* // => "text/plain"
|
||||
*
|
||||
* req.get('content-type');
|
||||
* // => "text/plain"
|
||||
*
|
||||
* req.get('Something');
|
||||
* // => undefined
|
||||
*
|
||||
* Aliased as `req.header()`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.get =
|
||||
req.header = function(name){
|
||||
switch (name = name.toLowerCase()) {
|
||||
case 'referer':
|
||||
case 'referrer':
|
||||
return this.headers.referrer
|
||||
|| this.headers.referer;
|
||||
default:
|
||||
return this.headers[name];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the given `type(s)` is acceptable, returning
|
||||
* the best match when true, otherwise `undefined`, in which
|
||||
* case you should respond with 406 "Not Acceptable".
|
||||
*
|
||||
* The `type` value may be a single mime type string
|
||||
* such as "application/json", the extension name
|
||||
* such as "json", a comma-delimted list such as "json, html, text/plain",
|
||||
* or an array `["json", "html", "text/plain"]`. When a list
|
||||
* or array is given the _best_ match, if any is returned.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // Accept: text/html
|
||||
* req.accepts('html');
|
||||
* // => "html"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* req.accepts('html');
|
||||
* // => "html"
|
||||
* req.accepts('text/html');
|
||||
* // => "text/html"
|
||||
* req.accepts('json, text');
|
||||
* // => "json"
|
||||
* req.accepts('application/json');
|
||||
* // => "application/json"
|
||||
*
|
||||
* // Accept: text/*, application/json
|
||||
* req.accepts('image/png');
|
||||
* req.accepts('png');
|
||||
* // => undefined
|
||||
*
|
||||
* // Accept: text/*;q=.5, application/json
|
||||
* req.accepts(['html', 'json']);
|
||||
* req.accepts('html, json');
|
||||
* // => "json"
|
||||
*
|
||||
* @param {String|Array} type(s)
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.accepts = function(type){
|
||||
return utils.accepts(type, this.get('Accept'));
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the given `charset` is acceptable,
|
||||
* otherwise you should respond with 406 "Not Acceptable".
|
||||
*
|
||||
* @param {String} charset
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.acceptsCharset = function(charset){
|
||||
var accepted = this.acceptedCharsets;
|
||||
return accepted.length
|
||||
? ~accepted.indexOf(charset)
|
||||
: true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the given `lang` is acceptable,
|
||||
* otherwise you should respond with 406 "Not Acceptable".
|
||||
*
|
||||
* @param {String} lang
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.acceptsLanguage = function(lang){
|
||||
var accepted = this.acceptedLanguages;
|
||||
return accepted.length
|
||||
? ~accepted.indexOf(lang)
|
||||
: true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse Range header field,
|
||||
* capping to the given `size`.
|
||||
*
|
||||
* Unspecified ranges such as "0-" require
|
||||
* knowledge of your resource length. In
|
||||
* the case of a byte range this is of course
|
||||
* the total number of bytes. If the Range
|
||||
* header field is not given `null` is returned,
|
||||
* `-1` when unsatisfiable, `-2` when syntactically invalid.
|
||||
*
|
||||
* NOTE: remember that ranges are inclusive, so
|
||||
* for example "Range: users=0-3" should respond
|
||||
* with 4 users when available, not 3.
|
||||
*
|
||||
* @param {Number} size
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.range = function(size){
|
||||
var range = this.get('Range');
|
||||
if (!range) return;
|
||||
return parseRange(size, range);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an array of Accepted media types
|
||||
* ordered from highest quality to lowest.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* [ { value: 'application/json',
|
||||
* quality: 1,
|
||||
* type: 'application',
|
||||
* subtype: 'json' },
|
||||
* { value: 'text/html',
|
||||
* quality: 0.5,
|
||||
* type: 'text',
|
||||
* subtype: 'html' } ]
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('accepted', function(){
|
||||
var accept = this.get('Accept');
|
||||
return accept
|
||||
? utils.parseAccept(accept)
|
||||
: [];
|
||||
});
|
||||
|
||||
/**
|
||||
* Return an array of Accepted languages
|
||||
* ordered from highest quality to lowest.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* Accept-Language: en;q=.5, en-us
|
||||
* ['en-us', 'en']
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('acceptedLanguages', function(){
|
||||
var accept = this.get('Accept-Language');
|
||||
return accept
|
||||
? utils
|
||||
.parseQuality(accept)
|
||||
.map(function(obj){
|
||||
return obj.value;
|
||||
})
|
||||
: [];
|
||||
});
|
||||
|
||||
/**
|
||||
* Return an array of Accepted charsets
|
||||
* ordered from highest quality to lowest.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* Accept-Charset: iso-8859-5;q=.2, unicode-1-1;q=0.8
|
||||
* ['unicode-1-1', 'iso-8859-5']
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('acceptedCharsets', function(){
|
||||
var accept = this.get('Accept-Charset');
|
||||
return accept
|
||||
? utils
|
||||
.parseQuality(accept)
|
||||
.map(function(obj){
|
||||
return obj.value;
|
||||
})
|
||||
: [];
|
||||
});
|
||||
|
||||
/**
|
||||
* Return the value of param `name` when present or `defaultValue`.
|
||||
*
|
||||
* - Checks route placeholders, ex: _/user/:id_
|
||||
* - Checks body params, ex: id=12, {"id":12}
|
||||
* - Checks query string params, ex: ?id=12
|
||||
*
|
||||
* To utilize request bodies, `req.body`
|
||||
* should be an object. This can be done by using
|
||||
* the `connect.bodyParser()` middleware.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Mixed} defaultValue
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.param = function(name, defaultValue){
|
||||
var params = this.params || {};
|
||||
var body = this.body || {};
|
||||
var query = this.query || {};
|
||||
if (null != params[name] && params.hasOwnProperty(name)) return params[name];
|
||||
if (null != body[name]) return body[name];
|
||||
if (null != query[name]) return query[name];
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the incoming request contains the "Content-Type"
|
||||
* header field, and it contains the give mime `type`.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // With Content-Type: text/html; charset=utf-8
|
||||
* req.is('html');
|
||||
* req.is('text/html');
|
||||
* req.is('text/*');
|
||||
* // => true
|
||||
*
|
||||
* // When Content-Type is application/json
|
||||
* req.is('json');
|
||||
* req.is('application/json');
|
||||
* req.is('application/*');
|
||||
* // => true
|
||||
*
|
||||
* req.is('html');
|
||||
* // => false
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.is = function(type){
|
||||
var ct = this.get('Content-Type');
|
||||
if (!ct) return false;
|
||||
ct = ct.split(';')[0];
|
||||
if (!~type.indexOf('/')) type = mime.lookup(type);
|
||||
if (~type.indexOf('*')) {
|
||||
type = type.split('/');
|
||||
ct = ct.split('/');
|
||||
if ('*' == type[0] && type[1] == ct[1]) return true;
|
||||
if ('*' == type[1] && type[0] == ct[0]) return true;
|
||||
return false;
|
||||
}
|
||||
return !! ~ct.indexOf(type);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the protocol string "http" or "https"
|
||||
* when requested with TLS. When the "trust proxy"
|
||||
* setting is enabled the "X-Forwarded-Proto" header
|
||||
* field will be trusted. If you're running behind
|
||||
* a reverse proxy that supplies https for you this
|
||||
* may be enabled.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('protocol', function(){
|
||||
var trustProxy = this.app.get('trust proxy');
|
||||
return this.connection.encrypted
|
||||
? 'https'
|
||||
: trustProxy
|
||||
? (this.get('X-Forwarded-Proto') || 'http')
|
||||
: 'http';
|
||||
});
|
||||
|
||||
/**
|
||||
* Short-hand for:
|
||||
*
|
||||
* req.protocol == 'https'
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('secure', function(){
|
||||
return 'https' == this.protocol;
|
||||
});
|
||||
|
||||
/**
|
||||
* Return the remote address, or when
|
||||
* "trust proxy" is `true` return
|
||||
* the upstream addr.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('ip', function(){
|
||||
return this.ips[0] || this.connection.remoteAddress;
|
||||
});
|
||||
|
||||
/**
|
||||
* When "trust proxy" is `true`, parse
|
||||
* the "X-Forwarded-For" ip address list.
|
||||
*
|
||||
* For example if the value were "client, proxy1, proxy2"
|
||||
* you would receive the array `["client", "proxy1", "proxy2"]`
|
||||
* where "proxy2" is the furthest down-stream.
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('ips', function(){
|
||||
var trustProxy = this.app.get('trust proxy');
|
||||
var val = this.get('X-Forwarded-For');
|
||||
return trustProxy && val
|
||||
? val.split(/ *, */)
|
||||
: [];
|
||||
});
|
||||
|
||||
/**
|
||||
* Return basic auth credentials.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // http://tobi:hello@example.com
|
||||
* req.auth
|
||||
* // => { username: 'tobi', password: 'hello' }
|
||||
*
|
||||
* @return {Object} or undefined
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('auth', function(){
|
||||
// missing
|
||||
var auth = this.get('Authorization');
|
||||
if (!auth) return;
|
||||
|
||||
// malformed
|
||||
var parts = auth.split(' ');
|
||||
if ('basic' != parts[0].toLowerCase()) return;
|
||||
if (!parts[1]) return;
|
||||
auth = parts[1];
|
||||
|
||||
// credentials
|
||||
auth = new Buffer(auth, 'base64').toString().split(':');
|
||||
return { username: auth[0], password: auth[1] };
|
||||
});
|
||||
|
||||
/**
|
||||
* Return subdomains as an array.
|
||||
*
|
||||
* For example "tobi.ferrets.example.com"
|
||||
* would provide `["ferrets", "tobi"]`.
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('subdomains', function(){
|
||||
return this.get('Host')
|
||||
.split('.')
|
||||
.slice(0, -2)
|
||||
.reverse();
|
||||
});
|
||||
|
||||
/**
|
||||
* Short-hand for `url.parse(req.url).pathname`.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('path', function(){
|
||||
return parse(this).pathname;
|
||||
});
|
||||
|
||||
/**
|
||||
* Parse the "Host" header field hostname.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('host', function(){
|
||||
return this.get('Host').split(':')[0];
|
||||
});
|
||||
|
||||
/**
|
||||
* Check if the request is fresh, aka
|
||||
* Last-Modified and/or the ETag
|
||||
* still match.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('fresh', function(){
|
||||
var method = this.method;
|
||||
var s = this.res.statusCode;
|
||||
|
||||
// GET or HEAD for weak freshness validation only
|
||||
if ('GET' != method && 'HEAD' != method) return false;
|
||||
|
||||
// 2xx or 304 as per rfc2616 14.26
|
||||
if ((s >= 200 && s < 300) || 304 == s) {
|
||||
return fresh(this.headers, this.res._headers);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Check if the request is stale, aka
|
||||
* "Last-Modified" and / or the "ETag" for the
|
||||
* resource has changed.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('stale', function(){
|
||||
return !this.fresh;
|
||||
});
|
||||
|
||||
/**
|
||||
* Check if the request was an _XMLHttpRequest_.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
req.__defineGetter__('xhr', function(){
|
||||
var val = this.get('X-Requested-With') || '';
|
||||
return 'xmlhttprequest' == val.toLowerCase();
|
||||
});
|
|
@ -0,0 +1,720 @@
|
|||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http')
|
||||
, path = require('path')
|
||||
, connect = require('connect')
|
||||
, utils = connect.utils
|
||||
, sign = require('cookie-signature').sign
|
||||
, normalizeType = require('./utils').normalizeType
|
||||
, normalizeTypes = require('./utils').normalizeTypes
|
||||
, etag = require('./utils').etag
|
||||
, statusCodes = http.STATUS_CODES
|
||||
, cookie = require('cookie')
|
||||
, send = require('send')
|
||||
, mime = connect.mime
|
||||
, basename = path.basename
|
||||
, extname = path.extname
|
||||
, join = path.join;
|
||||
|
||||
/**
|
||||
* Response prototype.
|
||||
*/
|
||||
|
||||
var res = module.exports = {
|
||||
__proto__: http.ServerResponse.prototype
|
||||
};
|
||||
|
||||
/**
|
||||
* Set status `code`.
|
||||
*
|
||||
* @param {Number} code
|
||||
* @return {ServerResponse}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.status = function(code){
|
||||
this.statusCode = code;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set Link header field with the given `links`.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* res.links({
|
||||
* next: 'http://api.example.com/users?page=2',
|
||||
* last: 'http://api.example.com/users?page=5'
|
||||
* });
|
||||
*
|
||||
* @param {Object} links
|
||||
* @return {ServerResponse}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.links = function(links){
|
||||
return this.set('Link', Object.keys(links).map(function(rel){
|
||||
return '<' + links[rel] + '>; rel="' + rel + '"';
|
||||
}).join(', '));
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a response.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* res.send(new Buffer('wahoo'));
|
||||
* res.send({ some: 'json' });
|
||||
* res.send('<p>some html</p>');
|
||||
* res.send(404, 'Sorry, cant find that');
|
||||
* res.send(404);
|
||||
*
|
||||
* @param {Mixed} body or status
|
||||
* @param {Mixed} body
|
||||
* @return {ServerResponse}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.send = function(body){
|
||||
var req = this.req
|
||||
, head = 'HEAD' == req.method
|
||||
, len;
|
||||
|
||||
// settings
|
||||
var app = this.app;
|
||||
|
||||
// allow status / body
|
||||
if (2 == arguments.length) {
|
||||
// res.send(body, status) backwards compat
|
||||
if ('number' != typeof body && 'number' == typeof arguments[1]) {
|
||||
this.statusCode = arguments[1];
|
||||
} else {
|
||||
this.statusCode = body;
|
||||
body = arguments[1];
|
||||
}
|
||||
}
|
||||
|
||||
switch (typeof body) {
|
||||
// response status
|
||||
case 'number':
|
||||
this.get('Content-Type') || this.type('txt');
|
||||
this.statusCode = body;
|
||||
body = http.STATUS_CODES[body];
|
||||
break;
|
||||
// string defaulting to html
|
||||
case 'string':
|
||||
if (!this.get('Content-Type')) {
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.type('html');
|
||||
}
|
||||
break;
|
||||
case 'boolean':
|
||||
case 'object':
|
||||
if (null == body) {
|
||||
body = '';
|
||||
} else if (Buffer.isBuffer(body)) {
|
||||
this.get('Content-Type') || this.type('bin');
|
||||
} else {
|
||||
return this.json(body);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// populate Content-Length
|
||||
if (undefined !== body && !this.get('Content-Length')) {
|
||||
this.set('Content-Length', len = Buffer.isBuffer(body)
|
||||
? body.length
|
||||
: Buffer.byteLength(body));
|
||||
}
|
||||
|
||||
// ETag support
|
||||
// TODO: W/ support
|
||||
if (app.settings.etag && len > 1024) {
|
||||
if (!this.get('ETag')) {
|
||||
this.set('ETag', etag(body));
|
||||
}
|
||||
}
|
||||
|
||||
// freshness
|
||||
if (req.fresh) this.statusCode = 304;
|
||||
|
||||
// strip irrelevant headers
|
||||
if (204 == this.statusCode || 304 == this.statusCode) {
|
||||
this.removeHeader('Content-Type');
|
||||
this.removeHeader('Content-Length');
|
||||
body = '';
|
||||
}
|
||||
|
||||
// respond
|
||||
this.end(head ? null : body);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send JSON response.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* res.json(null);
|
||||
* res.json({ user: 'tj' });
|
||||
* res.json(500, 'oh noes!');
|
||||
* res.json(404, 'I dont have that');
|
||||
*
|
||||
* @param {Mixed} obj or status
|
||||
* @param {Mixed} obj
|
||||
* @return {ServerResponse}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.json = function(obj){
|
||||
// allow status / body
|
||||
if (2 == arguments.length) {
|
||||
// res.json(body, status) backwards compat
|
||||
if ('number' == typeof arguments[1]) {
|
||||
this.statusCode = arguments[1];
|
||||
} else {
|
||||
this.statusCode = obj;
|
||||
obj = arguments[1];
|
||||
}
|
||||
}
|
||||
|
||||
// settings
|
||||
var app = this.app;
|
||||
var replacer = app.get('json replacer');
|
||||
var spaces = app.get('json spaces');
|
||||
var body = JSON.stringify(obj, replacer, spaces);
|
||||
|
||||
// content-type
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.get('Content-Type') || this.set('Content-Type', 'application/json');
|
||||
|
||||
return this.send(body);
|
||||
};
|
||||
|
||||
/**
|
||||
* Send JSON response with JSONP callback support.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* res.jsonp(null);
|
||||
* res.jsonp({ user: 'tj' });
|
||||
* res.jsonp(500, 'oh noes!');
|
||||
* res.jsonp(404, 'I dont have that');
|
||||
*
|
||||
* @param {Mixed} obj or status
|
||||
* @param {Mixed} obj
|
||||
* @return {ServerResponse}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.jsonp = function(obj){
|
||||
// allow status / body
|
||||
if (2 == arguments.length) {
|
||||
// res.json(body, status) backwards compat
|
||||
if ('number' == typeof arguments[1]) {
|
||||
this.statusCode = arguments[1];
|
||||
} else {
|
||||
this.statusCode = obj;
|
||||
obj = arguments[1];
|
||||
}
|
||||
}
|
||||
|
||||
// settings
|
||||
var app = this.app;
|
||||
var replacer = app.get('json replacer');
|
||||
var spaces = app.get('json spaces');
|
||||
var body = JSON.stringify(obj, replacer, spaces);
|
||||
var callback = this.req.query[app.get('jsonp callback name')];
|
||||
|
||||
// content-type
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.set('Content-Type', 'application/json');
|
||||
|
||||
// jsonp
|
||||
if (callback) {
|
||||
this.set('Content-Type', 'text/javascript');
|
||||
var cb = callback.replace(/[^\[\]\w$.]/g, '');
|
||||
body = cb + ' && ' + cb + '(' + body + ');';
|
||||
}
|
||||
|
||||
return this.send(body);
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfer the file at the given `path`.
|
||||
*
|
||||
* Automatically sets the _Content-Type_ response header field.
|
||||
* The callback `fn(err)` is invoked when the transfer is complete
|
||||
* or when an error occurs. Be sure to check `res.sentHeader`
|
||||
* if you wish to attempt responding, as the header and some data
|
||||
* may have already been transferred.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `maxAge` defaulting to 0
|
||||
* - `root` root directory for relative filenames
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* The following example illustrates how `res.sendfile()` may
|
||||
* be used as an alternative for the `static()` middleware for
|
||||
* dynamic situations. The code backing `res.sendfile()` is actually
|
||||
* the same code, so HTTP cache support etc is identical.
|
||||
*
|
||||
* app.get('/user/:uid/photos/:file', function(req, res){
|
||||
* var uid = req.params.uid
|
||||
* , file = req.params.file;
|
||||
*
|
||||
* req.user.mayViewFilesFrom(uid, function(yes){
|
||||
* if (yes) {
|
||||
* res.sendfile('/uploads/' + uid + '/' + file);
|
||||
* } else {
|
||||
* res.send(403, 'Sorry! you cant see that.');
|
||||
* }
|
||||
* });
|
||||
* });
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object|Function} options or fn
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.sendfile = function(path, options, fn){
|
||||
var self = this
|
||||
, req = self.req
|
||||
, next = this.req.next
|
||||
, options = options || {}
|
||||
, done;
|
||||
|
||||
// support function as second arg
|
||||
if ('function' == typeof options) {
|
||||
fn = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
// socket errors
|
||||
req.socket.on('error', error);
|
||||
|
||||
// errors
|
||||
function error(err) {
|
||||
if (done) return;
|
||||
done = true;
|
||||
|
||||
// clean up
|
||||
cleanup();
|
||||
if (!self.headerSent) self.removeHeader('Content-Disposition');
|
||||
|
||||
// callback available
|
||||
if (fn) return fn(err);
|
||||
|
||||
// list in limbo if there's no callback
|
||||
if (self.headerSent) return;
|
||||
|
||||
// delegate
|
||||
next(err);
|
||||
}
|
||||
|
||||
// streaming
|
||||
function stream() {
|
||||
if (done) return;
|
||||
cleanup();
|
||||
if (fn) self.on('finish', fn);
|
||||
}
|
||||
|
||||
// cleanup
|
||||
function cleanup() {
|
||||
req.socket.removeListener('error', error);
|
||||
}
|
||||
|
||||
// transfer
|
||||
var file = send(req, path);
|
||||
if (options.root) file.root(options.root);
|
||||
file.maxage(options.maxAge || 0);
|
||||
file.on('error', error);
|
||||
file.on('directory', next);
|
||||
file.on('stream', stream);
|
||||
file.pipe(this);
|
||||
this.on('finish', cleanup);
|
||||
};
|
||||
|
||||
/**
|
||||
* Transfer the file at the given `path` as an attachment.
|
||||
*
|
||||
* Optionally providing an alternate attachment `filename`,
|
||||
* and optional callback `fn(err)`. The callback is invoked
|
||||
* when the data transfer is complete, or when an error has
|
||||
* ocurred. Be sure to check `res.headerSent` if you plan to respond.
|
||||
*
|
||||
* This method uses `res.sendfile()`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {String|Function} filename or fn
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.download = function(path, filename, fn){
|
||||
// support function as second arg
|
||||
if ('function' == typeof filename) {
|
||||
fn = filename;
|
||||
filename = null;
|
||||
}
|
||||
|
||||
filename = filename || path;
|
||||
this.set('Content-Disposition', 'attachment; filename="' + basename(filename) + '"');
|
||||
return this.sendfile(path, fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set _Content-Type_ response header with `type` through `mime.lookup()`
|
||||
* when it does not contain "/", or set the Content-Type to `type` otherwise.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* res.type('.html');
|
||||
* res.type('html');
|
||||
* res.type('json');
|
||||
* res.type('application/json');
|
||||
* res.type('png');
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {ServerResponse} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.contentType =
|
||||
res.type = function(type){
|
||||
return this.set('Content-Type', ~type.indexOf('/')
|
||||
? type
|
||||
: mime.lookup(type));
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond to the Acceptable formats using an `obj`
|
||||
* of mime-type callbacks.
|
||||
*
|
||||
* This method uses `req.accepted`, an array of
|
||||
* acceptable types ordered by their quality values.
|
||||
* When "Accept" is not present the _first_ callback
|
||||
* is invoked, otherwise the first match is used. When
|
||||
* no match is performed the server responds with
|
||||
* 406 "Not Acceptable".
|
||||
*
|
||||
* Content-Type is set for you, however if you choose
|
||||
* you may alter this within the callback using `res.type()`
|
||||
* or `res.set('Content-Type', ...)`.
|
||||
*
|
||||
* res.format({
|
||||
* 'text/plain': function(){
|
||||
* res.send('hey');
|
||||
* },
|
||||
*
|
||||
* 'text/html': function(){
|
||||
* res.send('<p>hey</p>');
|
||||
* },
|
||||
*
|
||||
* 'appliation/json': function(){
|
||||
* res.send({ message: 'hey' });
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* In addition to canonicalized MIME types you may
|
||||
* also use extnames mapped to these types:
|
||||
*
|
||||
* res.format({
|
||||
* text: function(){
|
||||
* res.send('hey');
|
||||
* },
|
||||
*
|
||||
* html: function(){
|
||||
* res.send('<p>hey</p>');
|
||||
* },
|
||||
*
|
||||
* json: function(){
|
||||
* res.send({ message: 'hey' });
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* By default Express passes an `Error`
|
||||
* with a `.status` of 406 to `next(err)`
|
||||
* if a match is not made. If you provide
|
||||
* a `.default` callback it will be invoked
|
||||
* instead.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {ServerResponse} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.format = function(obj){
|
||||
var req = this.req
|
||||
, next = req.next;
|
||||
|
||||
var fn = obj.default;
|
||||
if (fn) delete obj.default;
|
||||
var keys = Object.keys(obj);
|
||||
|
||||
var key = req.accepts(keys);
|
||||
|
||||
this.set('Vary', 'Accept');
|
||||
|
||||
if (key) {
|
||||
this.set('Content-Type', normalizeType(key));
|
||||
obj[key](req, this, next);
|
||||
} else if (fn) {
|
||||
fn();
|
||||
} else {
|
||||
var err = new Error('Not Acceptable');
|
||||
err.status = 406;
|
||||
err.types = normalizeTypes(keys);
|
||||
next(err);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set _Content-Disposition_ header to _attachment_ with optional `filename`.
|
||||
*
|
||||
* @param {String} filename
|
||||
* @return {ServerResponse}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.attachment = function(filename){
|
||||
if (filename) this.type(extname(filename));
|
||||
this.set('Content-Disposition', filename
|
||||
? 'attachment; filename="' + basename(filename) + '"'
|
||||
: 'attachment');
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set header `field` to `val`, or pass
|
||||
* an object of header fields.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* res.set('Accept', 'application/json');
|
||||
* res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
|
||||
*
|
||||
* Aliased as `res.header()`.
|
||||
*
|
||||
* @param {String|Object} field
|
||||
* @param {String} val
|
||||
* @return {ServerResponse} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.set =
|
||||
res.header = function(field, val){
|
||||
if (2 == arguments.length) {
|
||||
this.setHeader(field, '' + val);
|
||||
} else {
|
||||
for (var key in field) {
|
||||
this.setHeader(key, '' + field[key]);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get value for header `field`.
|
||||
*
|
||||
* @param {String} field
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.get = function(field){
|
||||
return this.getHeader(field);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear cookie `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} options
|
||||
* @param {ServerResponse} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.clearCookie = function(name, options){
|
||||
var opts = { expires: new Date(1), path: '/' };
|
||||
return this.cookie(name, '', options
|
||||
? utils.merge(opts, options)
|
||||
: opts);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set cookie `name` to `val`, with the given `options`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `maxAge` max-age in milliseconds, converted to `expires`
|
||||
* - `signed` sign the cookie
|
||||
* - `path` defaults to "/"
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* // "Remember Me" for 15 minutes
|
||||
* res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
|
||||
*
|
||||
* // save as above
|
||||
* res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String|Object} val
|
||||
* @param {Options} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.cookie = function(name, val, options){
|
||||
options = options || {};
|
||||
var secret = this.req.secret;
|
||||
var signed = options.signed;
|
||||
if (signed && !secret) throw new Error('connect.cookieParser("secret") required for signed cookies');
|
||||
if ('object' == typeof val) val = 'j:' + JSON.stringify(val);
|
||||
if (signed) val = 's:' + sign(val, secret);
|
||||
if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge);
|
||||
if (null == options.path) options.path = '/';
|
||||
options.maxAge /= 1000;
|
||||
this.set('Set-Cookie', cookie.serialize(name, String(val), options));
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Redirect to the given `url` with optional response `status`
|
||||
* defaulting to 302.
|
||||
*
|
||||
* The given `url` can also be the name of a mapped url, for
|
||||
* example by default express supports "back" which redirects
|
||||
* to the _Referrer_ or _Referer_ headers or "/".
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* res.redirect('/foo/bar');
|
||||
* res.redirect('http://example.com');
|
||||
* res.redirect(301, 'http://example.com');
|
||||
* res.redirect('http://example.com', 301);
|
||||
* res.redirect('../login'); // /blog/post/1 -> /blog/login
|
||||
*
|
||||
* Mounting:
|
||||
*
|
||||
* When an application is mounted, and `res.redirect()`
|
||||
* is given a path that does _not_ lead with "/". For
|
||||
* example suppose a "blog" app is mounted at "/blog",
|
||||
* the following redirect would result in "/blog/login":
|
||||
*
|
||||
* res.redirect('login');
|
||||
*
|
||||
* While the leading slash would result in a redirect to "/login":
|
||||
*
|
||||
* res.redirect('/login');
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {Number} code
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.redirect = function(url){
|
||||
var app = this.app
|
||||
, req = this.req
|
||||
, head = 'HEAD' == req.method
|
||||
, status = 302
|
||||
, body;
|
||||
|
||||
// allow status / url
|
||||
if (2 == arguments.length) {
|
||||
if ('number' == typeof url) {
|
||||
status = url;
|
||||
url = arguments[1];
|
||||
} else {
|
||||
status = arguments[1];
|
||||
}
|
||||
}
|
||||
|
||||
// setup redirect map
|
||||
var map = { back: req.get('Referrer') || '/' };
|
||||
|
||||
// perform redirect
|
||||
url = map[url] || url;
|
||||
|
||||
// relative
|
||||
if (!~url.indexOf('://') && 0 != url.indexOf('//')) {
|
||||
var path = app.path();
|
||||
|
||||
// relative to path
|
||||
if ('.' == url[0]) {
|
||||
url = req.path + '/' + url;
|
||||
// relative to mount-point
|
||||
} else if ('/' != url[0]) {
|
||||
url = path + '/' + url;
|
||||
}
|
||||
}
|
||||
|
||||
// Support text/{plain,html} by default
|
||||
this.format({
|
||||
text: function(){
|
||||
body = statusCodes[status] + '. Redirecting to ' + encodeURI(url);
|
||||
},
|
||||
|
||||
html: function(){
|
||||
var u = utils.escape(url);
|
||||
body = '<p>' + statusCodes[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>';
|
||||
},
|
||||
|
||||
default: function(){
|
||||
body = '';
|
||||
}
|
||||
});
|
||||
|
||||
// Respond
|
||||
this.statusCode = status;
|
||||
this.set('Location', url);
|
||||
this.set('Content-Length', Buffer.byteLength(body));
|
||||
this.end(head ? null : body);
|
||||
};
|
||||
|
||||
/**
|
||||
* Render `view` with the given `options` and optional callback `fn`.
|
||||
* When a callback function is given a response will _not_ be made
|
||||
* automatically, otherwise a response of _200_ and _text/html_ is given.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `cache` boolean hinting to the engine it should cache
|
||||
* - `filename` filename of the view being rendered
|
||||
*
|
||||
* @param {String} view
|
||||
* @param {Object|Function} options or callback function
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.render = function(view, options, fn){
|
||||
var self = this
|
||||
, options = options || {}
|
||||
, req = this.req
|
||||
, app = req.app;
|
||||
|
||||
// support callback function as second arg
|
||||
if ('function' == typeof options) {
|
||||
fn = options, options = {};
|
||||
}
|
||||
|
||||
// merge res.locals
|
||||
options._locals = self.locals;
|
||||
|
||||
// default callback to respond
|
||||
fn = fn || function(err, str){
|
||||
if (err) return req.next(err);
|
||||
self.send(str);
|
||||
};
|
||||
|
||||
// render
|
||||
app.render(view, options, fn);
|
||||
};
|
|
@ -0,0 +1,256 @@
|
|||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Route = require('./route')
|
||||
, utils = require('../utils')
|
||||
, debug = require('debug')('express:router')
|
||||
, parse = require('connect').utils.parseUrl;
|
||||
|
||||
/**
|
||||
* Expose `Router` constructor.
|
||||
*/
|
||||
|
||||
exports = module.exports = Router;
|
||||
|
||||
/**
|
||||
* Initialize a new `Router` with the given `options`.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Router(options) {
|
||||
options = options || {};
|
||||
var self = this;
|
||||
this.map = {};
|
||||
this.params = {};
|
||||
this._params = [];
|
||||
this.caseSensitive = options.caseSensitive;
|
||||
this.strict = options.strict;
|
||||
this.middleware = function router(req, res, next){
|
||||
self._dispatch(req, res, next);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a param callback `fn` for the given `name`.
|
||||
*
|
||||
* @param {String|Function} name
|
||||
* @param {Function} fn
|
||||
* @return {Router} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Router.prototype.param = function(name, fn){
|
||||
// param logic
|
||||
if ('function' == typeof name) {
|
||||
this._params.push(name);
|
||||
return;
|
||||
}
|
||||
|
||||
// apply param functions
|
||||
var params = this._params
|
||||
, len = params.length
|
||||
, ret;
|
||||
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (ret = params[i](name, fn)) {
|
||||
fn = ret;
|
||||
}
|
||||
}
|
||||
|
||||
// ensure we end up with a
|
||||
// middleware function
|
||||
if ('function' != typeof fn) {
|
||||
throw new Error('invalid param() call for ' + name + ', got ' + fn);
|
||||
}
|
||||
|
||||
(this.params[name] = this.params[name] || []).push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Route dispatcher aka the route "middleware".
|
||||
*
|
||||
* @param {IncomingMessage} req
|
||||
* @param {ServerResponse} res
|
||||
* @param {Function} next
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype._dispatch = function(req, res, next){
|
||||
var params = this.params
|
||||
, self = this;
|
||||
|
||||
debug('dispatching %s %s (%s)', req.method, req.url, req.originalUrl);
|
||||
|
||||
// route dispatch
|
||||
(function pass(i, err){
|
||||
var paramCallbacks
|
||||
, paramIndex = 0
|
||||
, paramVal
|
||||
, route
|
||||
, keys
|
||||
, key;
|
||||
|
||||
// match next route
|
||||
function nextRoute(err) {
|
||||
pass(req._route_index + 1, err);
|
||||
}
|
||||
|
||||
// match route
|
||||
req.route = route = self.matchRequest(req, i);
|
||||
|
||||
// no route
|
||||
if (!route) return next(err);
|
||||
debug('matched %s %s', route.method, route.path);
|
||||
|
||||
// we have a route
|
||||
// start at param 0
|
||||
req.params = route.params;
|
||||
keys = route.keys;
|
||||
i = 0;
|
||||
|
||||
// param callbacks
|
||||
function param(err) {
|
||||
paramIndex = 0;
|
||||
key = keys[i++];
|
||||
paramVal = key && req.params[key.name];
|
||||
paramCallbacks = key && params[key.name];
|
||||
|
||||
try {
|
||||
if ('route' == err) {
|
||||
nextRoute();
|
||||
} else if (err) {
|
||||
i = 0;
|
||||
callbacks(err);
|
||||
} else if (paramCallbacks && undefined !== paramVal) {
|
||||
paramCallback();
|
||||
} else if (key) {
|
||||
param();
|
||||
} else {
|
||||
i = 0;
|
||||
callbacks();
|
||||
}
|
||||
} catch (err) {
|
||||
param(err);
|
||||
}
|
||||
};
|
||||
|
||||
param(err);
|
||||
|
||||
// single param callbacks
|
||||
function paramCallback(err) {
|
||||
var fn = paramCallbacks[paramIndex++];
|
||||
if (err || !fn) return param(err);
|
||||
fn(req, res, paramCallback, paramVal, key.name);
|
||||
}
|
||||
|
||||
// invoke route callbacks
|
||||
function callbacks(err) {
|
||||
var fn = route.callbacks[i++];
|
||||
try {
|
||||
if ('route' == err) {
|
||||
nextRoute();
|
||||
} else if (err && fn) {
|
||||
if (fn.length < 4) return callbacks(err);
|
||||
fn(err, req, res, callbacks);
|
||||
} else if (fn) {
|
||||
if (fn.length < 4) return fn(req, res, callbacks);
|
||||
callbacks();
|
||||
} else {
|
||||
nextRoute(err);
|
||||
}
|
||||
} catch (err) {
|
||||
callbacks(err);
|
||||
}
|
||||
}
|
||||
})(0);
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to match a route for `req`
|
||||
* with optional starting index of `i`
|
||||
* defaulting to 0.
|
||||
*
|
||||
* @param {IncomingMessage} req
|
||||
* @param {Number} i
|
||||
* @return {Route}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype.matchRequest = function(req, i, head){
|
||||
var method = req.method.toLowerCase()
|
||||
, url = parse(req)
|
||||
, path = url.pathname
|
||||
, routes = this.map
|
||||
, i = i || 0
|
||||
, route;
|
||||
|
||||
// HEAD support
|
||||
if (!head && 'head' == method) {
|
||||
route = this.matchRequest(req, i, true);
|
||||
if (route) return route;
|
||||
method = 'get';
|
||||
}
|
||||
|
||||
// routes for this method
|
||||
if (routes = routes[method]) {
|
||||
|
||||
// matching routes
|
||||
for (var len = routes.length; i < len; ++i) {
|
||||
route = routes[i];
|
||||
if (route.match(path)) {
|
||||
req._route_index = i;
|
||||
return route;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to match a route for `method`
|
||||
* and `url` with optional starting
|
||||
* index of `i` defaulting to 0.
|
||||
*
|
||||
* @param {String} method
|
||||
* @param {String} url
|
||||
* @param {Number} i
|
||||
* @return {Route}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype.match = function(method, url, i, head){
|
||||
var req = { method: method, url: url };
|
||||
return this.matchRequest(req, i, head);
|
||||
};
|
||||
|
||||
/**
|
||||
* Route `method`, `path`, and one or more callbacks.
|
||||
*
|
||||
* @param {String} method
|
||||
* @param {String} path
|
||||
* @param {Function} callback...
|
||||
* @return {Router} for chaining
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Router.prototype.route = function(method, path, callbacks){
|
||||
var method = method.toLowerCase()
|
||||
, callbacks = utils.flatten([].slice.call(arguments, 2));
|
||||
|
||||
// ensure path was given
|
||||
if (!path) throw new Error('Router#' + method + '() requires a path');
|
||||
|
||||
// create the route
|
||||
debug('defined %s %s', method, path);
|
||||
var route = new Route(method, path, callbacks, {
|
||||
sensitive: this.caseSensitive
|
||||
, strict: this.strict
|
||||
});
|
||||
|
||||
// add it
|
||||
(this.map[method] = this.map[method] || []).push(route);
|
||||
return this;
|
||||
};
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Expose `Route`.
|
||||
*/
|
||||
|
||||
module.exports = Route;
|
||||
|
||||
/**
|
||||
* Initialize `Route` with the given HTTP `method`, `path`,
|
||||
* and an array of `callbacks` and `options`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `sensitive` enable case-sensitive routes
|
||||
* - `strict` enable strict matching for trailing slashes
|
||||
*
|
||||
* @param {String} method
|
||||
* @param {String} path
|
||||
* @param {Array} callbacks
|
||||
* @param {Object} options.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Route(method, path, callbacks, options) {
|
||||
options = options || {};
|
||||
this.path = path;
|
||||
this.method = method;
|
||||
this.callbacks = callbacks;
|
||||
this.regexp = utils.pathRegexp(path
|
||||
, this.keys = []
|
||||
, options.sensitive
|
||||
, options.strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this route matches `path`, if so
|
||||
* populate `.params`.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Route.prototype.match = function(path){
|
||||
var keys = this.keys
|
||||
, params = this.params = []
|
||||
, m = this.regexp.exec(path);
|
||||
|
||||
if (!m) return false;
|
||||
|
||||
for (var i = 1, len = m.length; i < len; ++i) {
|
||||
var key = keys[i - 1];
|
||||
|
||||
var val = 'string' == typeof m[i]
|
||||
? decodeURIComponent(m[i])
|
||||
: m[i];
|
||||
|
||||
if (key) {
|
||||
params[key.name] = val;
|
||||
} else {
|
||||
params.push(val);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
|
@ -0,0 +1,282 @@
|
|||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var mime = require('connect').mime
|
||||
, crc32 = require('buffer-crc32');
|
||||
|
||||
/**
|
||||
* Return ETag for `body`.
|
||||
*
|
||||
* @param {String|Buffer} body
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.etag = function(body){
|
||||
return '"' + crc32.signed(body) + '"';
|
||||
};
|
||||
|
||||
/**
|
||||
* Make `locals()` bound to the given `obj`.
|
||||
*
|
||||
* This is used for `app.locals` and `res.locals`.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.locals = function(obj){
|
||||
obj.viewCallbacks = obj.viewCallbacks || [];
|
||||
|
||||
function locals(obj){
|
||||
for (var key in obj) locals[key] = obj[key];
|
||||
return obj;
|
||||
};
|
||||
|
||||
return locals;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if `path` looks absolute.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.isAbsolute = function(path){
|
||||
if ('/' == path[0]) return true;
|
||||
if (':' == path[1] && '\\' == path[2]) return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Flatten the given `arr`.
|
||||
*
|
||||
* @param {Array} arr
|
||||
* @return {Array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.flatten = function(arr, ret){
|
||||
var ret = ret || []
|
||||
, len = arr.length;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (Array.isArray(arr[i])) {
|
||||
exports.flatten(arr[i], ret);
|
||||
} else {
|
||||
ret.push(arr[i]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize the given `type`, for example "html" becomes "text/html".
|
||||
*
|
||||
* @param {String} type
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.normalizeType = function(type){
|
||||
return ~type.indexOf('/') ? type : mime.lookup(type);
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize `types`, for example "html" becomes "text/html".
|
||||
*
|
||||
* @param {Array} types
|
||||
* @return {Array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.normalizeTypes = function(types){
|
||||
var ret = [];
|
||||
|
||||
for (var i = 0; i < types.length; ++i) {
|
||||
ret.push(~types[i].indexOf('/')
|
||||
? types[i]
|
||||
: mime.lookup(types[i]));
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the acceptable type in `types`, if any.
|
||||
*
|
||||
* @param {Array} types
|
||||
* @param {String} str
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.acceptsArray = function(types, str){
|
||||
// accept anything when Accept is not present
|
||||
if (!str) return types[0];
|
||||
|
||||
// parse
|
||||
var accepted = exports.parseAccept(str)
|
||||
, normalized = exports.normalizeTypes(types)
|
||||
, len = accepted.length;
|
||||
|
||||
for (var i = 0; i < len; ++i) {
|
||||
for (var j = 0, jlen = types.length; j < jlen; ++j) {
|
||||
if (exports.accept(normalized[j].split('/'), accepted[i])) {
|
||||
return types[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if `type(s)` are acceptable based on
|
||||
* the given `str`.
|
||||
*
|
||||
* @param {String|Array} type(s)
|
||||
* @param {String} str
|
||||
* @return {Boolean|String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.accepts = function(type, str){
|
||||
if ('string' == typeof type) type = type.split(/ *, */);
|
||||
return exports.acceptsArray(type, str);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if `type` array is acceptable for `other`.
|
||||
*
|
||||
* @param {Array} type
|
||||
* @param {Object} other
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.accept = function(type, other){
|
||||
return (type[0] == other.type || '*' == other.type)
|
||||
&& (type[1] == other.subtype || '*' == other.subtype);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse accept `str`, returning
|
||||
* an array objects containing
|
||||
* `.type` and `.subtype` along
|
||||
* with the values provided by
|
||||
* `parseQuality()`.
|
||||
*
|
||||
* @param {Type} name
|
||||
* @return {Type}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.parseAccept = function(str){
|
||||
return exports
|
||||
.parseQuality(str)
|
||||
.map(function(obj){
|
||||
var parts = obj.value.split('/');
|
||||
obj.type = parts[0];
|
||||
obj.subtype = parts[1];
|
||||
return obj;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse quality `str`, returning an
|
||||
* array of objects with `.value` and
|
||||
* `.quality`.
|
||||
*
|
||||
* @param {Type} name
|
||||
* @return {Type}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.parseQuality = function(str){
|
||||
return str
|
||||
.split(/ *, */)
|
||||
.map(quality)
|
||||
.filter(function(obj){
|
||||
return obj.quality;
|
||||
})
|
||||
.sort(function(a, b){
|
||||
return b.quality - a.quality;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse quality `str` returning an
|
||||
* object with `.value` and `.quality`.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function quality(str) {
|
||||
var parts = str.split(/ *; */)
|
||||
, val = parts[0];
|
||||
|
||||
var q = parts[1]
|
||||
? parseFloat(parts[1].split(/ *= */)[1])
|
||||
: 1;
|
||||
|
||||
return { value: val, quality: q };
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape special characters in the given string of html.
|
||||
*
|
||||
* @param {String} html
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.escape = function(html) {
|
||||
return String(html)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize the given path string,
|
||||
* returning a regular expression.
|
||||
*
|
||||
* An empty array should be passed,
|
||||
* which will contain the placeholder
|
||||
* key names. For example "/user/:id" will
|
||||
* then contain ["id"].
|
||||
*
|
||||
* @param {String|RegExp|Array} path
|
||||
* @param {Array} keys
|
||||
* @param {Boolean} sensitive
|
||||
* @param {Boolean} strict
|
||||
* @return {RegExp}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.pathRegexp = function(path, keys, sensitive, strict) {
|
||||
if (path instanceof RegExp) return path;
|
||||
if (Array.isArray(path)) path = '(' + path.join('|') + ')';
|
||||
path = path
|
||||
.concat(strict ? '' : '/?')
|
||||
.replace(/\/\(/g, '(?:/')
|
||||
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g, function(_, slash, format, key, capture, optional, star){
|
||||
keys.push({ name: key, optional: !! optional });
|
||||
slash = slash || '';
|
||||
return ''
|
||||
+ (optional ? '' : slash)
|
||||
+ '(?:'
|
||||
+ (optional ? slash : '')
|
||||
+ (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')'
|
||||
+ (optional || '')
|
||||
+ (star ? '(/*)?' : '');
|
||||
})
|
||||
.replace(/([\/.])/g, '\\$1')
|
||||
.replace(/\*/g, '(.*)');
|
||||
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var path = require('path')
|
||||
, fs = require('fs')
|
||||
, utils = require('./utils')
|
||||
, dirname = path.dirname
|
||||
, basename = path.basename
|
||||
, extname = path.extname
|
||||
, exists = fs.existsSync || path.existsSync
|
||||
, join = path.join;
|
||||
|
||||
/**
|
||||
* Expose `View`.
|
||||
*/
|
||||
|
||||
module.exports = View;
|
||||
|
||||
/**
|
||||
* Initialize a new `View` with the given `name`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `defaultEngine` the default template engine name
|
||||
* - `engines` template engine require() cache
|
||||
* - `root` root path for view lookup
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} options
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function View(name, options) {
|
||||
options = options || {};
|
||||
this.name = name;
|
||||
this.root = options.root;
|
||||
var engines = options.engines;
|
||||
this.defaultEngine = options.defaultEngine;
|
||||
var ext = this.ext = extname(name);
|
||||
if (!ext) name += (ext = this.ext = '.' + this.defaultEngine);
|
||||
this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
|
||||
this.path = this.lookup(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup view by the given `path`
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
View.prototype.lookup = function(path){
|
||||
var ext = this.ext;
|
||||
|
||||
// <path>.<engine>
|
||||
if (!utils.isAbsolute(path)) path = join(this.root, path);
|
||||
if (exists(path)) return path;
|
||||
|
||||
// <path>/index.<engine>
|
||||
path = join(dirname(path), basename(path, ext), 'index' + ext);
|
||||
if (exists(path)) return path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Render with the given `options` and callback `fn(err, str)`.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {Function} fn
|
||||
* @api private
|
||||
*/
|
||||
|
||||
View.prototype.render = function(options, fn){
|
||||
this.engine(this.path, options, fn);
|
||||
};
|
1
nodeartnet/node_modules/express/node_modules/buffer-crc32/.npmignore
generated
vendored
Normal file
1
nodeartnet/node_modules/express/node_modules/buffer-crc32/.npmignore
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules
|
8
nodeartnet/node_modules/express/node_modules/buffer-crc32/.travis.yml
generated
vendored
Normal file
8
nodeartnet/node_modules/express/node_modules/buffer-crc32/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- brianloveswords@gmail.com
|
33
nodeartnet/node_modules/express/node_modules/buffer-crc32/README.md
generated
vendored
Normal file
33
nodeartnet/node_modules/express/node_modules/buffer-crc32/README.md
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
# buffer-crc32
|
||||
|
||||
[![Build Status](https://secure.travis-ci.org/brianloveswords/buffer-crc32.png?branch=master)](http://travis-ci.org/brianloveswords/buffer-crc32)
|
||||
|
||||
crc32 that works with binary data and fancy character sets, outputs
|
||||
buffer, signed or unsigned data and has tests.
|
||||
|
||||
Derived from the sample CRC implementation in the PNG specification: http://www.w3.org/TR/PNG/#D-CRCAppendix
|
||||
|
||||
# install
|
||||
```
|
||||
npm install buffer-crc32
|
||||
```
|
||||
|
||||
# example
|
||||
```js
|
||||
var crc32 = require('buffer-crc32');
|
||||
// works with buffers
|
||||
var buf = Buffer([[0x00, 0x73, 0x75, 0x70, 0x20, 0x62, 0x72, 0x6f, 0x00])
|
||||
crc32(buf) // -> <Buffer 94 5a ab 4a>
|
||||
|
||||
// has convenience methods for getting signed or unsigned ints
|
||||
crc32.signed(buf) // -> -1805997238
|
||||
crc32.unsigned(buf) // -> 2488970058
|
||||
|
||||
// will cast to buffer if given a string, so you can
|
||||
// directly use foreign characters safely
|
||||
crc32('自動販売機') // -> <Buffer cb 03 1a c5>
|
||||
```
|
||||
|
||||
# tests
|
||||
This was tested against the output of zlib's crc32 method. You can run
|
||||
the tests with`npm test` (requires tap)
|
84
nodeartnet/node_modules/express/node_modules/buffer-crc32/index.js
generated
vendored
Normal file
84
nodeartnet/node_modules/express/node_modules/buffer-crc32/index.js
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
var Buffer = require('buffer').Buffer;
|
||||
|
||||
var CRC_TABLE = [
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
|
||||
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
|
||||
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
|
||||
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
|
||||
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
|
||||
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
|
||||
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
|
||||
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
|
||||
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
|
||||
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
|
||||
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
|
||||
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
|
||||
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
|
||||
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
|
||||
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
|
||||
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
|
||||
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
|
||||
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
|
||||
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
|
||||
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
|
||||
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
|
||||
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
|
||||
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
|
||||
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
|
||||
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
|
||||
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
|
||||
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
|
||||
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
|
||||
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
|
||||
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
|
||||
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
|
||||
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
|
||||
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
|
||||
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
|
||||
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
|
||||
0x2d02ef8d
|
||||
];
|
||||
|
||||
function bufferizeInt(num) {
|
||||
var tmp = Buffer(4);
|
||||
tmp.writeInt32BE(num, 0);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
function _crc32(buf) {
|
||||
if (!Buffer.isBuffer(buf))
|
||||
buf = Buffer(buf);
|
||||
var crc = 0xffffffff;
|
||||
for (var n = 0; n < buf.length; n++) {
|
||||
crc = CRC_TABLE[(crc ^ buf[n]) & 0xff] ^ (crc >>> 8);
|
||||
}
|
||||
return (crc ^ 0xffffffff);
|
||||
}
|
||||
|
||||
function crc32() {
|
||||
return bufferizeInt(_crc32.apply(null, arguments));
|
||||
}
|
||||
crc32.signed = function () {
|
||||
return _crc32.apply(null, arguments);
|
||||
};
|
||||
crc32.unsigned = function () {
|
||||
return crc32.apply(null, arguments).readUInt32BE(0);
|
||||
};
|
||||
|
||||
module.exports = crc32;
|
36
nodeartnet/node_modules/express/node_modules/buffer-crc32/package.json
generated
vendored
Normal file
36
nodeartnet/node_modules/express/node_modules/buffer-crc32/package.json
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"author": {
|
||||
"name": "Brian J. Brennan",
|
||||
"email": "brianloveswords@gmail.com",
|
||||
"url": "http://bjb.io"
|
||||
},
|
||||
"name": "buffer-crc32",
|
||||
"description": "A pure javascript CRC32 algorithm that plays nice with binary data",
|
||||
"version": "0.1.1",
|
||||
"homepage": "https://github.com/brianloveswords/buffer-crc32",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/brianloveswords/buffer-crc32.git"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "./node_modules/.bin/tap tests/*.test.js"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"tap": "~0.2.5"
|
||||
},
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"_id": "buffer-crc32@0.1.1",
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.4",
|
||||
"_nodeVersion": "v0.6.12",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "0a86b58034139c6de8742e157e7ab91792848593"
|
||||
},
|
||||
"_from": "buffer-crc32@0.1.1"
|
||||
}
|
52
nodeartnet/node_modules/express/node_modules/buffer-crc32/tests/crc.test.js
generated
vendored
Normal file
52
nodeartnet/node_modules/express/node_modules/buffer-crc32/tests/crc.test.js
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
var crc32 = require('..');
|
||||
var test = require('tap').test;
|
||||
|
||||
test('simple crc32 is no problem', function (t) {
|
||||
var input = Buffer('hey sup bros');
|
||||
var expected = Buffer([0x47, 0xfa, 0x55, 0x70]);
|
||||
t.same(crc32(input), expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('another simple one', function (t) {
|
||||
var input = Buffer('IEND');
|
||||
var expected = Buffer([0xae, 0x42, 0x60, 0x82]);
|
||||
t.same(crc32(input), expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('slightly more complex', function (t) {
|
||||
var input = Buffer([0x00, 0x00, 0x00]);
|
||||
var expected = Buffer([0xff, 0x41, 0xd9, 0x12]);
|
||||
t.same(crc32(input), expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('complex crc32 gets calculated like a champ', function (t) {
|
||||
var input = Buffer('शीर्षक');
|
||||
var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]);
|
||||
t.same(crc32(input), expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('casts to buffer if necessary', function (t) {
|
||||
var input = 'शीर्षक';
|
||||
var expected = Buffer([0x17, 0xb8, 0xaf, 0xf1]);
|
||||
t.same(crc32(input), expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('can do unsigned', function (t) {
|
||||
var input = 'ham sandwich';
|
||||
var expected = -1891873021;
|
||||
t.same(crc32.signed(input), expected);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('can do signed', function (t) {
|
||||
var input = 'bear sandwich';
|
||||
var expected = 3711466352;
|
||||
t.same(crc32.unsigned(input), expected);
|
||||
t.end();
|
||||
});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
support
|
||||
test
|
||||
examples
|
||||
*.sock
|
|
@ -0,0 +1,4 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.4
|
||||
- 0.6
|
107
nodeartnet/node_modules/express/node_modules/commander/History.md
generated
vendored
Normal file
107
nodeartnet/node_modules/express/node_modules/commander/History.md
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
|
||||
0.6.1 / 2012-06-01
|
||||
==================
|
||||
|
||||
* Added: append (yes or no) on confirmation
|
||||
* Added: allow node.js v0.7.x
|
||||
|
||||
0.6.0 / 2012-04-10
|
||||
==================
|
||||
|
||||
* Added `.prompt(obj, callback)` support. Closes #49
|
||||
* Added default support to .choose(). Closes #41
|
||||
* Fixed the choice example
|
||||
|
||||
0.5.1 / 2011-12-20
|
||||
==================
|
||||
|
||||
* Fixed `password()` for recent nodes. Closes #36
|
||||
|
||||
0.5.0 / 2011-12-04
|
||||
==================
|
||||
|
||||
* Added sub-command option support [itay]
|
||||
|
||||
0.4.3 / 2011-12-04
|
||||
==================
|
||||
|
||||
* Fixed custom help ordering. Closes #32
|
||||
|
||||
0.4.2 / 2011-11-24
|
||||
==================
|
||||
|
||||
* Added travis support
|
||||
* Fixed: line-buffered input automatically trimmed. Closes #31
|
||||
|
||||
0.4.1 / 2011-11-18
|
||||
==================
|
||||
|
||||
* Removed listening for "close" on --help
|
||||
|
||||
0.4.0 / 2011-11-15
|
||||
==================
|
||||
|
||||
* Added support for `--`. Closes #24
|
||||
|
||||
0.3.3 / 2011-11-14
|
||||
==================
|
||||
|
||||
* Fixed: wait for close event when writing help info [Jerry Hamlet]
|
||||
|
||||
0.3.2 / 2011-11-01
|
||||
==================
|
||||
|
||||
* Fixed long flag definitions with values [felixge]
|
||||
|
||||
0.3.1 / 2011-10-31
|
||||
==================
|
||||
|
||||
* Changed `--version` short flag to `-V` from `-v`
|
||||
* Changed `.version()` so it's configurable [felixge]
|
||||
|
||||
0.3.0 / 2011-10-31
|
||||
==================
|
||||
|
||||
* Added support for long flags only. Closes #18
|
||||
|
||||
0.2.1 / 2011-10-24
|
||||
==================
|
||||
|
||||
* "node": ">= 0.4.x < 0.7.0". Closes #20
|
||||
|
||||
0.2.0 / 2011-09-26
|
||||
==================
|
||||
|
||||
* Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs]
|
||||
|
||||
0.1.0 / 2011-08-24
|
||||
==================
|
||||
|
||||
* Added support for custom `--help` output
|
||||
|
||||
0.0.5 / 2011-08-18
|
||||
==================
|
||||
|
||||
* Changed: when the user enters nothing prompt for password again
|
||||
* Fixed issue with passwords beginning with numbers [NuckChorris]
|
||||
|
||||
0.0.4 / 2011-08-15
|
||||
==================
|
||||
|
||||
* Fixed `Commander#args`
|
||||
|
||||
0.0.3 / 2011-08-15
|
||||
==================
|
||||
|
||||
* Added default option value support
|
||||
|
||||
0.0.2 / 2011-08-15
|
||||
==================
|
||||
|
||||
* Added mask support to `Command#password(str[, mask], fn)`
|
||||
* Added `Command#password(str, fn)`
|
||||
|
||||
0.0.1 / 2010-01-03
|
||||
==================
|
||||
|
||||
* Initial release
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
TESTS = $(shell find test/test.*.js)
|
||||
|
||||
test:
|
||||
@./test/run $(TESTS)
|
||||
|
||||
.PHONY: test
|
|
@ -0,0 +1,262 @@
|
|||
# Commander.js
|
||||
|
||||
The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander).
|
||||
|
||||
[![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js)
|
||||
|
||||
## Installation
|
||||
|
||||
$ npm install commander
|
||||
|
||||
## Option parsing
|
||||
|
||||
Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.
|
||||
|
||||
```js
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var program = require('commander');
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-p, --peppers', 'Add peppers')
|
||||
.option('-P, --pineapple', 'Add pineapple')
|
||||
.option('-b, --bbq', 'Add bbq sauce')
|
||||
.option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
|
||||
.parse(process.argv);
|
||||
|
||||
console.log('you ordered a pizza with:');
|
||||
if (program.peppers) console.log(' - peppers');
|
||||
if (program.pineapple) console.log(' - pineappe');
|
||||
if (program.bbq) console.log(' - bbq');
|
||||
console.log(' - %s cheese', program.cheese);
|
||||
```
|
||||
|
||||
Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc.
|
||||
|
||||
## Automated --help
|
||||
|
||||
The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
|
||||
|
||||
```
|
||||
$ ./examples/pizza --help
|
||||
|
||||
Usage: pizza [options]
|
||||
|
||||
Options:
|
||||
|
||||
-V, --version output the version number
|
||||
-p, --peppers Add peppers
|
||||
-P, --pineapple Add pineappe
|
||||
-b, --bbq Add bbq sauce
|
||||
-c, --cheese <type> Add the specified type of cheese [marble]
|
||||
-h, --help output usage information
|
||||
|
||||
```
|
||||
|
||||
## Coercion
|
||||
|
||||
```js
|
||||
function range(val) {
|
||||
return val.split('..').map(Number);
|
||||
}
|
||||
|
||||
function list(val) {
|
||||
return val.split(',');
|
||||
}
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.usage('[options] <file ...>')
|
||||
.option('-i, --integer <n>', 'An integer argument', parseInt)
|
||||
.option('-f, --float <n>', 'A float argument', parseFloat)
|
||||
.option('-r, --range <a>..<b>', 'A range', range)
|
||||
.option('-l, --list <items>', 'A list', list)
|
||||
.option('-o, --optional [value]', 'An optional value')
|
||||
.parse(process.argv);
|
||||
|
||||
console.log(' int: %j', program.integer);
|
||||
console.log(' float: %j', program.float);
|
||||
console.log(' optional: %j', program.optional);
|
||||
program.range = program.range || [];
|
||||
console.log(' range: %j..%j', program.range[0], program.range[1]);
|
||||
console.log(' list: %j', program.list);
|
||||
console.log(' args: %j', program.args);
|
||||
```
|
||||
|
||||
## Custom help
|
||||
|
||||
You can display arbitrary `-h, --help` information
|
||||
by listening for "--help". Commander will automatically
|
||||
exit once you are done so that the remainder of your program
|
||||
does not execute causing undesired behaviours, for example
|
||||
in the following executable "stuff" will not output when
|
||||
`--help` is used.
|
||||
|
||||
```js
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var program = require('../');
|
||||
|
||||
function list(val) {
|
||||
return val.split(',').map(Number);
|
||||
}
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-f, --foo', 'enable some foo')
|
||||
.option('-b, --bar', 'enable some bar')
|
||||
.option('-B, --baz', 'enable some baz');
|
||||
|
||||
// must be before .parse() since
|
||||
// node's emit() is immediate
|
||||
|
||||
program.on('--help', function(){
|
||||
console.log(' Examples:');
|
||||
console.log('');
|
||||
console.log(' $ custom-help --help');
|
||||
console.log(' $ custom-help -h');
|
||||
console.log('');
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
||||
|
||||
console.log('stuff');
|
||||
```
|
||||
|
||||
yielding the following help output:
|
||||
|
||||
```
|
||||
|
||||
Usage: custom-help [options]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
-V, --version output the version number
|
||||
-f, --foo enable some foo
|
||||
-b, --bar enable some bar
|
||||
-B, --baz enable some baz
|
||||
|
||||
Examples:
|
||||
|
||||
$ custom-help --help
|
||||
$ custom-help -h
|
||||
|
||||
```
|
||||
|
||||
## .prompt(msg, fn)
|
||||
|
||||
Single-line prompt:
|
||||
|
||||
```js
|
||||
program.prompt('name: ', function(name){
|
||||
console.log('hi %s', name);
|
||||
});
|
||||
```
|
||||
|
||||
Multi-line prompt:
|
||||
|
||||
```js
|
||||
program.prompt('description:', function(name){
|
||||
console.log('hi %s', name);
|
||||
});
|
||||
```
|
||||
|
||||
Coercion:
|
||||
|
||||
```js
|
||||
program.prompt('Age: ', Number, function(age){
|
||||
console.log('age: %j', age);
|
||||
});
|
||||
```
|
||||
|
||||
```js
|
||||
program.prompt('Birthdate: ', Date, function(date){
|
||||
console.log('date: %s', date);
|
||||
});
|
||||
```
|
||||
|
||||
## .password(msg[, mask], fn)
|
||||
|
||||
Prompt for password without echoing:
|
||||
|
||||
```js
|
||||
program.password('Password: ', function(pass){
|
||||
console.log('got "%s"', pass);
|
||||
process.stdin.destroy();
|
||||
});
|
||||
```
|
||||
|
||||
Prompt for password with mask char "*":
|
||||
|
||||
```js
|
||||
program.password('Password: ', '*', function(pass){
|
||||
console.log('got "%s"', pass);
|
||||
process.stdin.destroy();
|
||||
});
|
||||
```
|
||||
|
||||
## .confirm(msg, fn)
|
||||
|
||||
Confirm with the given `msg`:
|
||||
|
||||
```js
|
||||
program.confirm('continue? ', function(ok){
|
||||
console.log(' got %j', ok);
|
||||
});
|
||||
```
|
||||
|
||||
## .choose(list, fn)
|
||||
|
||||
Let the user choose from a `list`:
|
||||
|
||||
```js
|
||||
var list = ['tobi', 'loki', 'jane', 'manny', 'luna'];
|
||||
|
||||
console.log('Choose the coolest pet:');
|
||||
program.choose(list, function(i){
|
||||
console.log('you chose %d "%s"', i, list[i]);
|
||||
});
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
- [API documentation](http://visionmedia.github.com/commander.js/)
|
||||
- [ascii tables](https://github.com/LearnBoost/cli-table)
|
||||
- [progress bars](https://github.com/visionmedia/node-progress)
|
||||
- [more progress bars](https://github.com/substack/node-multimeter)
|
||||
- [examples](https://github.com/visionmedia/commander.js/tree/master/examples)
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
module.exports = require('./lib/commander');
|
1026
nodeartnet/node_modules/express/node_modules/commander/lib/commander.js
generated
vendored
Normal file
1026
nodeartnet/node_modules/express/node_modules/commander/lib/commander.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
41
nodeartnet/node_modules/express/node_modules/commander/package.json
generated
vendored
Normal file
41
nodeartnet/node_modules/express/node_modules/commander/package.json
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "commander",
|
||||
"version": "0.6.1",
|
||||
"description": "the complete solution for node.js command-line programs",
|
||||
"keywords": [
|
||||
"command",
|
||||
"option",
|
||||
"parser",
|
||||
"prompt",
|
||||
"stdin"
|
||||
],
|
||||
"author": {
|
||||
"name": "TJ Holowaychuk",
|
||||
"email": "tj@vision-media.ca"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/visionmedia/commander.js.git"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"should": ">= 0.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"main": "index",
|
||||
"engines": {
|
||||
"node": ">= 0.4.x"
|
||||
},
|
||||
"_id": "commander@0.6.1",
|
||||
"optionalDependencies": {},
|
||||
"_engineSupported": true,
|
||||
"_npmVersion": "1.1.4",
|
||||
"_nodeVersion": "v0.6.12",
|
||||
"_defaultsLoaded": true,
|
||||
"dist": {
|
||||
"shasum": "badadd584ce9604fa9eb33c82ee6e182b626b6c0"
|
||||
},
|
||||
"_from": "commander@0.6.1"
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
*.markdown
|
||||
*.md
|
||||
.git*
|
||||
Makefile
|
||||
benchmarks/
|
||||
docs/
|
||||
examples/
|
||||
install.sh
|
||||
support/
|
||||
test/
|
||||
.DS_Store
|
||||
coverage.html
|
|
@ -0,0 +1,5 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
- 0.9
|
|
@ -0,0 +1,24 @@
|
|||
(The MIT License)
|
||||
|
||||
Copyright (c) 2010 Sencha Inc.
|
||||
Copyright (c) 2011 LearnBoost
|
||||
Copyright (c) 2011 TJ Holowaychuk
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
module.exports = process.env.CONNECT_COV
|
||||
? require('./lib-cov/connect')
|
||||
: require('./lib/connect');
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
/*!
|
||||
* Connect - Cache
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Expose `Cache`.
|
||||
*/
|
||||
|
||||
module.exports = Cache;
|
||||
|
||||
/**
|
||||
* LRU cache store.
|
||||
*
|
||||
* @param {Number} limit
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Cache(limit) {
|
||||
this.store = {};
|
||||
this.keys = [];
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Touch `key`, promoting the object.
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Number} i
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Cache.prototype.touch = function(key, i){
|
||||
this.keys.splice(i,1);
|
||||
this.keys.push(key);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove `key`.
|
||||
*
|
||||
* @param {String} key
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Cache.prototype.remove = function(key){
|
||||
delete this.store[key];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the object stored for `key`.
|
||||
*
|
||||
* @param {String} key
|
||||
* @return {Array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Cache.prototype.get = function(key){
|
||||
return this.store[key];
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a cache `key`.
|
||||
*
|
||||
* @param {String} key
|
||||
* @return {Array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Cache.prototype.add = function(key){
|
||||
// initialize store
|
||||
var len = this.keys.push(key);
|
||||
|
||||
// limit reached, invalidate LRU
|
||||
if (len > this.limit) this.remove(this.keys.shift());
|
||||
|
||||
var arr = this.store[key] = [];
|
||||
arr.createdAt = new Date;
|
||||
return arr;
|
||||
};
|
93
nodeartnet/node_modules/express/node_modules/connect/lib/connect.js
generated
vendored
Normal file
93
nodeartnet/node_modules/express/node_modules/connect/lib/connect.js
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
|
||||
/*!
|
||||
* Connect
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
, proto = require('./proto')
|
||||
, utils = require('./utils')
|
||||
, path = require('path')
|
||||
, basename = path.basename
|
||||
, fs = require('fs');
|
||||
|
||||
// node patches
|
||||
|
||||
require('./patch');
|
||||
|
||||
// expose createServer() as the module
|
||||
|
||||
exports = module.exports = createServer;
|
||||
|
||||
/**
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
exports.version = '2.6.1';
|
||||
|
||||
/**
|
||||
* Expose mime module.
|
||||
*/
|
||||
|
||||
exports.mime = require('./middleware/static').mime;
|
||||
|
||||
/**
|
||||
* Expose the prototype.
|
||||
*/
|
||||
|
||||
exports.proto = proto;
|
||||
|
||||
/**
|
||||
* Auto-load middleware getters.
|
||||
*/
|
||||
|
||||
exports.middleware = {};
|
||||
|
||||
/**
|
||||
* Expose utilities.
|
||||
*/
|
||||
|
||||
exports.utils = utils;
|
||||
|
||||
/**
|
||||
* Create a new connect server.
|
||||
*
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function createServer() {
|
||||
function app(req, res){ app.handle(req, res); }
|
||||
utils.merge(app, proto);
|
||||
utils.merge(app, EventEmitter.prototype);
|
||||
app.route = '/';
|
||||
app.stack = [];
|
||||
for (var i = 0; i < arguments.length; ++i) {
|
||||
app.use(arguments[i]);
|
||||
}
|
||||
return app;
|
||||
};
|
||||
|
||||
/**
|
||||
* Support old `.createServer()` method.
|
||||
*/
|
||||
|
||||
createServer.createServer = createServer;
|
||||
|
||||
/**
|
||||
* Auto-load bundled middleware with getters.
|
||||
*/
|
||||
|
||||
fs.readdirSync(__dirname + '/middleware').forEach(function(filename){
|
||||
if (!/\.js$/.test(filename)) return;
|
||||
var name = basename(filename, '.js');
|
||||
function load(){ return require('./middleware/' + name); }
|
||||
exports.middleware.__defineGetter__(name, load);
|
||||
exports.__defineGetter__(name, load);
|
||||
});
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
/**
|
||||
* Connect is a middleware framework for node,
|
||||
* shipping with over 18 bundled middleware and a rich selection of
|
||||
* 3rd-party middleware.
|
||||
*
|
||||
* var app = connect()
|
||||
* .use(connect.logger('dev'))
|
||||
* .use(connect.static('public'))
|
||||
* .use(function(req, res){
|
||||
* res.end('hello world\n');
|
||||
* })
|
||||
* .listen(3000);
|
||||
*
|
||||
* Installation:
|
||||
*
|
||||
* $ npm install connect
|
||||
*
|
||||
* Middleware:
|
||||
*
|
||||
* - [logger](logger.html) request logger with custom format support
|
||||
* - [csrf](csrf.html) Cross-site request forgery protection
|
||||
* - [compress](compress.html) Gzip compression middleware
|
||||
* - [basicAuth](basicAuth.html) basic http authentication
|
||||
* - [bodyParser](bodyParser.html) extensible request body parser
|
||||
* - [json](json.html) application/json parser
|
||||
* - [urlencoded](urlencoded.html) application/x-www-form-urlencoded parser
|
||||
* - [multipart](multipart.html) multipart/form-data parser
|
||||
* - [timeout](timeout.html) request timeouts
|
||||
* - [cookieParser](cookieParser.html) cookie parser
|
||||
* - [session](session.html) session management support with bundled MemoryStore
|
||||
* - [cookieSession](cookieSession.html) cookie-based session support
|
||||
* - [methodOverride](methodOverride.html) faux HTTP method support
|
||||
* - [responseTime](responseTime.html) calculates response-time and exposes via X-Response-Time
|
||||
* - [staticCache](staticCache.html) memory cache layer for the static() middleware
|
||||
* - [static](static.html) streaming static file server supporting `Range` and more
|
||||
* - [directory](directory.html) directory listing middleware
|
||||
* - [vhost](vhost.html) virtual host sub-domain mapping middleware
|
||||
* - [favicon](favicon.html) efficient favicon server (with default icon)
|
||||
* - [limit](limit.html) limit the bytesize of request bodies
|
||||
* - [query](query.html) automatic querystring parser, populating `req.query`
|
||||
* - [errorHandler](errorHandler.html) flexible error handler
|
||||
*
|
||||
* Links:
|
||||
*
|
||||
* - list of [3rd-party](https://github.com/senchalabs/connect/wiki) middleware
|
||||
* - GitHub [repository](http://github.com/senchalabs/connect)
|
||||
* - [test documentation](https://github.com/senchalabs/connect/blob/gh-pages/tests.md)
|
||||
*
|
||||
*/
|
103
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js
generated
vendored
Normal file
103
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
|
||||
/*!
|
||||
* Connect - basicAuth
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, unauthorized = utils.unauthorized;
|
||||
|
||||
/**
|
||||
* Basic Auth:
|
||||
*
|
||||
* Enfore basic authentication by providing a `callback(user, pass)`,
|
||||
* which must return `true` in order to gain access. Alternatively an async
|
||||
* method is provided as well, invoking `callback(user, pass, callback)`. Populates
|
||||
* `req.user`. The final alternative is simply passing username / password
|
||||
* strings.
|
||||
*
|
||||
* Simple username and password
|
||||
*
|
||||
* connect(connect.basicAuth('username', 'password'));
|
||||
*
|
||||
* Callback verification
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.basicAuth(function(user, pass){
|
||||
* return 'tj' == user & 'wahoo' == pass;
|
||||
* }))
|
||||
*
|
||||
* Async callback verification, accepting `fn(err, user)`.
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.basicAuth(function(user, pass, fn){
|
||||
* User.authenticate({ user: user, pass: pass }, fn);
|
||||
* }))
|
||||
*
|
||||
* @param {Function|String} callback or username
|
||||
* @param {String} realm
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function basicAuth(callback, realm) {
|
||||
var username, password;
|
||||
|
||||
// user / pass strings
|
||||
if ('string' == typeof callback) {
|
||||
username = callback;
|
||||
password = realm;
|
||||
if ('string' != typeof password) throw new Error('password argument required');
|
||||
realm = arguments[2];
|
||||
callback = function(user, pass){
|
||||
return user == username && pass == password;
|
||||
}
|
||||
}
|
||||
|
||||
realm = realm || 'Authorization Required';
|
||||
|
||||
return function(req, res, next) {
|
||||
var authorization = req.headers.authorization;
|
||||
|
||||
if (req.user) return next();
|
||||
if (!authorization) return unauthorized(res, realm);
|
||||
|
||||
var parts = authorization.split(' ');
|
||||
|
||||
if (parts.length !== 2) return next(utils.error(400));
|
||||
|
||||
var scheme = parts[0]
|
||||
, credentials = new Buffer(parts[1], 'base64').toString()
|
||||
, index = credentials.indexOf(':');
|
||||
|
||||
if ('Basic' != scheme || index < 0) return next(utils.error(400));
|
||||
|
||||
var user = credentials.slice(0, index)
|
||||
, pass = credentials.slice(index + 1);
|
||||
|
||||
// async
|
||||
if (callback.length >= 3) {
|
||||
var pause = utils.pause(req);
|
||||
callback(user, pass, function(err, user){
|
||||
if (err || !user) return unauthorized(res, realm);
|
||||
req.user = req.remoteUser = user;
|
||||
next();
|
||||
pause.resume();
|
||||
});
|
||||
// sync
|
||||
} else {
|
||||
if (callback(user, pass)) {
|
||||
req.user = req.remoteUser = user;
|
||||
next();
|
||||
} else {
|
||||
unauthorized(res, realm);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
61
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js
generated
vendored
Normal file
61
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
|
||||
/*!
|
||||
* Connect - bodyParser
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var multipart = require('./multipart')
|
||||
, urlencoded = require('./urlencoded')
|
||||
, json = require('./json');
|
||||
|
||||
/**
|
||||
* Body parser:
|
||||
*
|
||||
* Parse request bodies, supports _application/json_,
|
||||
* _application/x-www-form-urlencoded_, and _multipart/form-data_.
|
||||
*
|
||||
* This is equivalent to:
|
||||
*
|
||||
* app.use(connect.json());
|
||||
* app.use(connect.urlencoded());
|
||||
* app.use(connect.multipart());
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.bodyParser())
|
||||
* .use(function(req, res) {
|
||||
* res.end('viewing user ' + req.body.user.name);
|
||||
* });
|
||||
*
|
||||
* $ curl -d 'user[name]=tj' http://local/
|
||||
* $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://local/
|
||||
*
|
||||
* View [json](json.html), [urlencoded](urlencoded.html), and [multipart](multipart.html) for more info.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function bodyParser(options){
|
||||
var _urlencoded = urlencoded(options)
|
||||
, _multipart = multipart(options)
|
||||
, _json = json(options);
|
||||
|
||||
return function bodyParser(req, res, next) {
|
||||
_json(req, res, function(err){
|
||||
if (err) return next(err);
|
||||
_urlencoded(req, res, function(err){
|
||||
if (err) return next(err);
|
||||
_multipart(req, res, next);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
147
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/compress.js
generated
vendored
Normal file
147
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/compress.js
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*!
|
||||
* Connect - compress
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var zlib = require('zlib');
|
||||
|
||||
/**
|
||||
* Supported content-encoding methods.
|
||||
*/
|
||||
|
||||
exports.methods = {
|
||||
gzip: zlib.createGzip
|
||||
, deflate: zlib.createDeflate
|
||||
};
|
||||
|
||||
/**
|
||||
* Default filter function.
|
||||
*/
|
||||
|
||||
exports.filter = function(req, res){
|
||||
return /json|text|javascript/.test(res.getHeader('Content-Type'));
|
||||
};
|
||||
|
||||
/**
|
||||
* Compress:
|
||||
*
|
||||
* Compress response data with gzip/deflate.
|
||||
*
|
||||
* Filter:
|
||||
*
|
||||
* A `filter` callback function may be passed to
|
||||
* replace the default logic of:
|
||||
*
|
||||
* exports.filter = function(req, res){
|
||||
* return /json|text|javascript/.test(res.getHeader('Content-Type'));
|
||||
* };
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* All remaining options are passed to the gzip/deflate
|
||||
* creation functions. Consult node's docs for additional details.
|
||||
*
|
||||
* - `chunkSize` (default: 16*1024)
|
||||
* - `windowBits`
|
||||
* - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression
|
||||
* - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more
|
||||
* - `strategy`: compression strategy
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function compress(options) {
|
||||
options = options || {};
|
||||
var names = Object.keys(exports.methods)
|
||||
, filter = options.filter || exports.filter;
|
||||
|
||||
return function(req, res, next){
|
||||
var accept = req.headers['accept-encoding']
|
||||
, write = res.write
|
||||
, end = res.end
|
||||
, stream
|
||||
, method;
|
||||
|
||||
// vary
|
||||
res.setHeader('Vary', 'Accept-Encoding');
|
||||
|
||||
// proxy
|
||||
|
||||
res.write = function(chunk, encoding){
|
||||
if (!this.headerSent) this._implicitHeader();
|
||||
return stream
|
||||
? stream.write(new Buffer(chunk, encoding))
|
||||
: write.call(res, chunk, encoding);
|
||||
};
|
||||
|
||||
res.end = function(chunk, encoding){
|
||||
if (chunk) this.write(chunk, encoding);
|
||||
return stream
|
||||
? stream.end()
|
||||
: end.call(res);
|
||||
};
|
||||
|
||||
res.on('header', function(){
|
||||
var encoding = res.getHeader('Content-Encoding') || 'identity';
|
||||
|
||||
// already encoded
|
||||
if ('identity' != encoding) return;
|
||||
|
||||
// default request filter
|
||||
if (!filter(req, res)) return;
|
||||
|
||||
// SHOULD use identity
|
||||
if (!accept) return;
|
||||
|
||||
// head
|
||||
if ('HEAD' == req.method) return;
|
||||
|
||||
// default to gzip
|
||||
if ('*' == accept.trim()) method = 'gzip';
|
||||
|
||||
// compression method
|
||||
if (!method) {
|
||||
for (var i = 0, len = names.length; i < len; ++i) {
|
||||
if (~accept.indexOf(names[i])) {
|
||||
method = names[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compression method
|
||||
if (!method) return;
|
||||
|
||||
// compression stream
|
||||
stream = exports.methods[method](options);
|
||||
|
||||
// header fields
|
||||
res.setHeader('Content-Encoding', method);
|
||||
res.removeHeader('Content-Length');
|
||||
|
||||
// compression
|
||||
|
||||
stream.on('data', function(chunk){
|
||||
write.call(res, chunk);
|
||||
});
|
||||
|
||||
stream.on('end', function(){
|
||||
end.call(res);
|
||||
});
|
||||
|
||||
stream.on('drain', function() {
|
||||
res.emit('drain');
|
||||
});
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
62
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js
generated
vendored
Normal file
62
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
|
||||
/*!
|
||||
* Connect - cookieParser
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('./../utils')
|
||||
, cookie = require('cookie');
|
||||
|
||||
/**
|
||||
* Cookie parser:
|
||||
*
|
||||
* Parse _Cookie_ header and populate `req.cookies`
|
||||
* with an object keyed by the cookie names. Optionally
|
||||
* you may enabled signed cookie support by passing
|
||||
* a `secret` string, which assigns `req.secret` so
|
||||
* it may be used by other middleware.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.cookieParser('optional secret string'))
|
||||
* .use(function(req, res, next){
|
||||
* res.end(JSON.stringify(req.cookies));
|
||||
* })
|
||||
*
|
||||
* @param {String} secret
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function cookieParser(secret){
|
||||
return function cookieParser(req, res, next) {
|
||||
if (req.cookies) return next();
|
||||
var cookies = req.headers.cookie;
|
||||
|
||||
req.secret = secret;
|
||||
req.cookies = {};
|
||||
req.signedCookies = {};
|
||||
|
||||
if (cookies) {
|
||||
try {
|
||||
req.cookies = cookie.parse(cookies);
|
||||
if (secret) {
|
||||
req.signedCookies = utils.parseSignedCookies(req.cookies, secret);
|
||||
req.signedCookies = utils.parseJSONCookies(req.signedCookies);
|
||||
}
|
||||
req.cookies = utils.parseJSONCookies(req.cookies);
|
||||
} catch (err) {
|
||||
err.status = 400;
|
||||
return next(err);
|
||||
}
|
||||
}
|
||||
next();
|
||||
};
|
||||
};
|
115
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/cookieSession.js
generated
vendored
Normal file
115
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/cookieSession.js
generated
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
|
||||
/*!
|
||||
* Connect - cookieSession
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('./../utils')
|
||||
, Cookie = require('./session/cookie')
|
||||
, debug = require('debug')('connect:cookieSession')
|
||||
, signature = require('cookie-signature')
|
||||
, crc16 = require('crc').crc16;
|
||||
|
||||
/**
|
||||
* Cookie Session:
|
||||
*
|
||||
* Cookie session middleware.
|
||||
*
|
||||
* var app = connect();
|
||||
* app.use(connect.cookieParser());
|
||||
* app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }}));
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `key` cookie name defaulting to `connect.sess`
|
||||
* - `secret` prevents cookie tampering
|
||||
* - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`
|
||||
* - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")
|
||||
*
|
||||
* Clearing sessions:
|
||||
*
|
||||
* To clear the session simply set its value to `null`,
|
||||
* `cookieSession()` will then respond with a 1970 Set-Cookie.
|
||||
*
|
||||
* req.session = null;
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function cookieSession(options){
|
||||
// TODO: utilize Session/Cookie to unify API
|
||||
options = options || {};
|
||||
var key = options.key || 'connect.sess'
|
||||
, trustProxy = options.proxy;
|
||||
|
||||
return function cookieSession(req, res, next) {
|
||||
|
||||
// req.secret is for backwards compatibility
|
||||
var secret = options.secret || req.secret;
|
||||
if (!secret) throw new Error('`secret` option required for cookie sessions');
|
||||
|
||||
// default session
|
||||
req.session = {};
|
||||
var cookie = req.session.cookie = new Cookie(options.cookie);
|
||||
|
||||
// pathname mismatch
|
||||
if (0 != req.originalUrl.indexOf(cookie.path)) return next();
|
||||
|
||||
// cookieParser secret
|
||||
if (!options.secret && req.secret) {
|
||||
req.session = req.signedCookies[key] || {};
|
||||
} else {
|
||||
// TODO: refactor
|
||||
var rawCookie = req.cookies[key];
|
||||
if (rawCookie) {
|
||||
var unsigned = utils.parseSignedCookie(rawCookie, secret);
|
||||
if (unsigned) {
|
||||
var originalHash = crc16(unsigned);
|
||||
req.session = utils.parseJSONCookie(unsigned) || {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.on('header', function(){
|
||||
// removed
|
||||
if (!req.session) {
|
||||
debug('clear session');
|
||||
cookie.expires = new Date(0);
|
||||
res.setHeader('Set-Cookie', cookie.serialize(key, ''));
|
||||
return;
|
||||
}
|
||||
|
||||
delete req.session.cookie;
|
||||
|
||||
// check security
|
||||
var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
|
||||
, tls = req.connection.encrypted || (trustProxy && 'https' == proto)
|
||||
, secured = cookie.secure && tls;
|
||||
|
||||
// only send secure cookies via https
|
||||
if (cookie.secure && !secured) return debug('not secured');
|
||||
|
||||
// serialize
|
||||
debug('serializing %j', req.session);
|
||||
var val = 'j:' + JSON.stringify(req.session);
|
||||
|
||||
// compare hashes, no need to set-cookie if unchanged
|
||||
if (originalHash == crc16(val)) return debug('unmodified session');
|
||||
|
||||
// set-cookie
|
||||
val = 's:' + signature.sign(val, secret);
|
||||
val = cookie.serialize(key, val);
|
||||
debug('set-cookie %j', cookie);
|
||||
res.setHeader('Set-Cookie', val);
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
73
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/csrf.js
generated
vendored
Normal file
73
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/csrf.js
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*!
|
||||
* Connect - csrf
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Anti CSRF:
|
||||
*
|
||||
* CRSF protection middleware.
|
||||
*
|
||||
* By default this middleware generates a token named "_csrf"
|
||||
* which should be added to requests which mutate
|
||||
* state, within a hidden form field, query-string etc. This
|
||||
* token is validated against the visitor's `req.session._csrf`
|
||||
* property.
|
||||
*
|
||||
* The default `value` function checks `req.body` generated
|
||||
* by the `bodyParser()` middleware, `req.query` generated
|
||||
* by `query()`, and the "X-CSRF-Token" header field.
|
||||
*
|
||||
* This middleware requires session support, thus should be added
|
||||
* somewhere _below_ `session()` and `cookieParser()`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `value` a function accepting the request, returning the token
|
||||
*
|
||||
* @param {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function csrf(options) {
|
||||
options = options || {};
|
||||
var value = options.value || defaultValue;
|
||||
|
||||
return function(req, res, next){
|
||||
// generate CSRF token
|
||||
var token = req.session._csrf || (req.session._csrf = utils.uid(24));
|
||||
|
||||
// ignore these methods
|
||||
if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next();
|
||||
|
||||
// determine value
|
||||
var val = value(req);
|
||||
|
||||
// check
|
||||
if (val != token) return next(utils.error(403));
|
||||
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Default value function, checking the `req.body`
|
||||
* and `req.query` for the CSRF token.
|
||||
*
|
||||
* @param {IncomingMessage} req
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function defaultValue(req) {
|
||||
return (req.body && req.body._csrf)
|
||||
|| (req.query && req.query._csrf)
|
||||
|| (req.headers['x-csrf-token']);
|
||||
}
|
229
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/directory.js
generated
vendored
Normal file
229
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/directory.js
generated
vendored
Normal file
|
@ -0,0 +1,229 @@
|
|||
|
||||
/*!
|
||||
* Connect - directory
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
// TODO: icon / style for directories
|
||||
// TODO: arrow key navigation
|
||||
// TODO: make icons extensible
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var fs = require('fs')
|
||||
, parse = require('url').parse
|
||||
, utils = require('../utils')
|
||||
, path = require('path')
|
||||
, normalize = path.normalize
|
||||
, extname = path.extname
|
||||
, join = path.join;
|
||||
|
||||
/*!
|
||||
* Icon cache.
|
||||
*/
|
||||
|
||||
var cache = {};
|
||||
|
||||
/**
|
||||
* Directory:
|
||||
*
|
||||
* Serve directory listings with the given `root` path.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `hidden` display hidden (dot) files. Defaults to false.
|
||||
* - `icons` display icons. Defaults to false.
|
||||
* - `filter` Apply this filter function to files. Defaults to false.
|
||||
*
|
||||
* @param {String} root
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function directory(root, options){
|
||||
options = options || {};
|
||||
|
||||
// root required
|
||||
if (!root) throw new Error('directory() root path required');
|
||||
var hidden = options.hidden
|
||||
, icons = options.icons
|
||||
, filter = options.filter
|
||||
, root = normalize(root);
|
||||
|
||||
return function directory(req, res, next) {
|
||||
if ('GET' != req.method && 'HEAD' != req.method) return next();
|
||||
|
||||
var accept = req.headers.accept || 'text/plain'
|
||||
, url = parse(req.url)
|
||||
, dir = decodeURIComponent(url.pathname)
|
||||
, path = normalize(join(root, dir))
|
||||
, originalUrl = parse(req.originalUrl)
|
||||
, originalDir = decodeURIComponent(originalUrl.pathname)
|
||||
, showUp = path != root && path != root + '/';
|
||||
|
||||
// null byte(s), bad request
|
||||
if (~path.indexOf('\0')) return next(utils.error(400));
|
||||
|
||||
// malicious path, forbidden
|
||||
if (0 != path.indexOf(root)) return next(utils.error(403));
|
||||
|
||||
// check if we have a directory
|
||||
fs.stat(path, function(err, stat){
|
||||
if (err) return 'ENOENT' == err.code
|
||||
? next()
|
||||
: next(err);
|
||||
|
||||
if (!stat.isDirectory()) return next();
|
||||
|
||||
// fetch files
|
||||
fs.readdir(path, function(err, files){
|
||||
if (err) return next(err);
|
||||
if (!hidden) files = removeHidden(files);
|
||||
if (filter) files = files.filter(filter);
|
||||
files.sort();
|
||||
|
||||
// content-negotiation
|
||||
for (var key in exports) {
|
||||
if (~accept.indexOf(key) || ~accept.indexOf('*/*')) {
|
||||
exports[key](req, res, files, next, originalDir, showUp, icons);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// not acceptable
|
||||
next(utils.error(406));
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with text/html.
|
||||
*/
|
||||
|
||||
exports.html = function(req, res, files, next, dir, showUp, icons){
|
||||
fs.readFile(__dirname + '/../public/directory.html', 'utf8', function(err, str){
|
||||
if (err) return next(err);
|
||||
fs.readFile(__dirname + '/../public/style.css', 'utf8', function(err, style){
|
||||
if (err) return next(err);
|
||||
if (showUp) files.unshift('..');
|
||||
str = str
|
||||
.replace('{style}', style)
|
||||
.replace('{files}', html(files, dir, icons))
|
||||
.replace('{directory}', dir)
|
||||
.replace('{linked-path}', htmlPath(dir));
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
res.setHeader('Content-Length', str.length);
|
||||
res.end(str);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with application/json.
|
||||
*/
|
||||
|
||||
exports.json = function(req, res, files){
|
||||
files = JSON.stringify(files);
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.setHeader('Content-Length', files.length);
|
||||
res.end(files);
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with text/plain.
|
||||
*/
|
||||
|
||||
exports.plain = function(req, res, files){
|
||||
files = files.join('\n') + '\n';
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.setHeader('Content-Length', files.length);
|
||||
res.end(files);
|
||||
};
|
||||
|
||||
/**
|
||||
* Map html `dir`, returning a linked path.
|
||||
*/
|
||||
|
||||
function htmlPath(dir) {
|
||||
var curr = [];
|
||||
return dir.split('/').map(function(part){
|
||||
curr.push(part);
|
||||
return '<a href="' + curr.join('/') + '">' + part + '</a>';
|
||||
}).join(' / ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Map html `files`, returning an html unordered list.
|
||||
*/
|
||||
|
||||
function html(files, dir, useIcons) {
|
||||
return '<ul id="files">' + files.map(function(file){
|
||||
var icon = ''
|
||||
, classes = [];
|
||||
|
||||
if (useIcons && '..' != file) {
|
||||
icon = icons[extname(file)] || icons.default;
|
||||
icon = '<img src="data:image/png;base64,' + load(icon) + '" />';
|
||||
classes.push('icon');
|
||||
}
|
||||
|
||||
return '<li><a href="'
|
||||
+ join(dir, file)
|
||||
+ '" class="'
|
||||
+ classes.join(' ') + '"'
|
||||
+ ' title="' + file + '">'
|
||||
+ icon + file + '</a></li>';
|
||||
|
||||
}).join('\n') + '</ul>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and cache the given `icon`.
|
||||
*
|
||||
* @param {String} icon
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function load(icon) {
|
||||
if (cache[icon]) return cache[icon];
|
||||
return cache[icon] = fs.readFileSync(__dirname + '/../public/icons/' + icon, 'base64');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter "hidden" `files`, aka files
|
||||
* beginning with a `.`.
|
||||
*
|
||||
* @param {Array} files
|
||||
* @return {Array}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function removeHidden(files) {
|
||||
return files.filter(function(file){
|
||||
return '.' != file[0];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Icon map.
|
||||
*/
|
||||
|
||||
var icons = {
|
||||
'.js': 'page_white_code_red.png'
|
||||
, '.c': 'page_white_c.png'
|
||||
, '.h': 'page_white_h.png'
|
||||
, '.cc': 'page_white_cplusplus.png'
|
||||
, '.php': 'page_white_php.png'
|
||||
, '.rb': 'page_white_ruby.png'
|
||||
, '.cpp': 'page_white_cplusplus.png'
|
||||
, '.swf': 'page_white_flash.png'
|
||||
, '.pdf': 'page_white_acrobat.png'
|
||||
, 'default': 'page_white.png'
|
||||
};
|
86
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
generated
vendored
Normal file
86
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*!
|
||||
* Connect - errorHandler
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, fs = require('fs');
|
||||
|
||||
// environment
|
||||
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
/**
|
||||
* Error handler:
|
||||
*
|
||||
* Development error handler, providing stack traces
|
||||
* and error message responses for requests accepting text, html,
|
||||
* or json.
|
||||
*
|
||||
* Text:
|
||||
*
|
||||
* By default, and when _text/plain_ is accepted a simple stack trace
|
||||
* or error message will be returned.
|
||||
*
|
||||
* JSON:
|
||||
*
|
||||
* When _application/json_ is accepted, connect will respond with
|
||||
* an object in the form of `{ "error": error }`.
|
||||
*
|
||||
* HTML:
|
||||
*
|
||||
* When accepted connect will output a nice html stack trace.
|
||||
*
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function errorHandler(){
|
||||
return function errorHandler(err, req, res, next){
|
||||
if (err.status) res.statusCode = err.status;
|
||||
if (res.statusCode < 400) res.statusCode = 500;
|
||||
if ('test' != env) console.error(err.stack);
|
||||
var accept = req.headers.accept || '';
|
||||
// html
|
||||
if (~accept.indexOf('html')) {
|
||||
fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){
|
||||
fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){
|
||||
var stack = (err.stack || '')
|
||||
.split('\n').slice(1)
|
||||
.map(function(v){ return '<li>' + v + '</li>'; }).join('');
|
||||
html = html
|
||||
.replace('{style}', style)
|
||||
.replace('{stack}', stack)
|
||||
.replace('{title}', exports.title)
|
||||
.replace('{statusCode}', res.statusCode)
|
||||
.replace(/\{error\}/g, utils.escape(err.toString()));
|
||||
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
||||
res.end(html);
|
||||
});
|
||||
});
|
||||
// json
|
||||
} else if (~accept.indexOf('json')) {
|
||||
var error = { message: err.message, stack: err.stack };
|
||||
for (var prop in err) error[prop] = err[prop];
|
||||
var json = JSON.stringify({ error: error });
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(json);
|
||||
// plain text
|
||||
} else {
|
||||
res.writeHead(res.statusCode, { 'Content-Type': 'text/plain' });
|
||||
res.end(err.stack);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Template title, framework authors may override this value.
|
||||
*/
|
||||
|
||||
exports.title = 'Connect';
|
81
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/favicon.js
generated
vendored
Normal file
81
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/favicon.js
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
|
||||
/*!
|
||||
* Connect - favicon
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var fs = require('fs')
|
||||
, utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Favicon:
|
||||
*
|
||||
* By default serves the connect favicon, or the favicon
|
||||
* located by the given `path`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `maxAge` cache-control max-age directive, defaulting to 1 day
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* Serve default favicon:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.favicon())
|
||||
*
|
||||
* Serve favicon before logging for brevity:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.favicon())
|
||||
* .use(connect.logger('dev'))
|
||||
*
|
||||
* Serve custom favicon:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.favicon('public/favicon.ico))
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function favicon(path, options){
|
||||
var options = options || {}
|
||||
, path = path || __dirname + '/../public/favicon.ico'
|
||||
, maxAge = options.maxAge || 86400000
|
||||
, icon; // favicon cache
|
||||
|
||||
return function favicon(req, res, next){
|
||||
if ('/favicon.ico' == req.url) {
|
||||
if (icon) {
|
||||
res.writeHead(200, icon.headers);
|
||||
res.end(icon.body);
|
||||
} else {
|
||||
fs.readFile(path, function(err, buf){
|
||||
if (err) return next(err);
|
||||
icon = {
|
||||
headers: {
|
||||
'Content-Type': 'image/x-icon'
|
||||
, 'Content-Length': buf.length
|
||||
, 'ETag': '"' + utils.md5(buf) + '"'
|
||||
, 'Cache-Control': 'public, max-age=' + (maxAge / 1000)
|
||||
},
|
||||
body: buf
|
||||
};
|
||||
res.writeHead(200, icon.headers);
|
||||
res.end(icon.body);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
};
|
81
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/json.js
generated
vendored
Normal file
81
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/json.js
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
|
||||
/*!
|
||||
* Connect - json
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, _limit = require('./limit');
|
||||
|
||||
/**
|
||||
* noop middleware.
|
||||
*/
|
||||
|
||||
function noop(req, res, next) {
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON:
|
||||
*
|
||||
* Parse JSON request bodies, providing the
|
||||
* parsed object as `req.body`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `strict` when `false` anything `JSON.parse()` accepts will be parsed
|
||||
* - `reviver` used as the second "reviver" argument for JSON.parse
|
||||
* - `limit` byte limit disabled by default
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function(options){
|
||||
var options = options || {}
|
||||
, strict = options.strict !== false;
|
||||
|
||||
var limit = options.limit
|
||||
? _limit(options.limit)
|
||||
: noop;
|
||||
|
||||
return function json(req, res, next) {
|
||||
if (req._body) return next();
|
||||
req.body = req.body || {};
|
||||
|
||||
if (!utils.hasBody(req)) return next();
|
||||
|
||||
// check Content-Type
|
||||
if ('application/json' != utils.mime(req)) return next();
|
||||
|
||||
// flag as parsed
|
||||
req._body = true;
|
||||
|
||||
// parse
|
||||
limit(req, res, function(err){
|
||||
if (err) return next(err);
|
||||
var buf = '';
|
||||
req.setEncoding('utf8');
|
||||
req.on('data', function(chunk){ buf += chunk });
|
||||
req.on('end', function(){
|
||||
var first = buf.trim()[0];
|
||||
if (strict && '{' != first && '[' != first) return next(utils.error(400, 'invalid json'));
|
||||
try {
|
||||
req.body = JSON.parse(buf, options.reviver);
|
||||
next();
|
||||
} catch (err){
|
||||
err.body = buf;
|
||||
err.status = 400;
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
55
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/limit.js
generated
vendored
Normal file
55
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/limit.js
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
/*!
|
||||
* Connect - limit
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Limit:
|
||||
*
|
||||
* Limit request bodies to the given size in `bytes`.
|
||||
*
|
||||
* A string representation of the bytesize may also be passed,
|
||||
* for example "5mb", "200kb", "1gb", etc.
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.limit('5.5mb'))
|
||||
* .use(handleImageUpload)
|
||||
*
|
||||
* @param {Number|String} bytes
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function limit(bytes){
|
||||
if ('string' == typeof bytes) bytes = utils.parseBytes(bytes);
|
||||
if ('number' != typeof bytes) throw new Error('limit() bytes required');
|
||||
return function limit(req, res, next){
|
||||
var received = 0
|
||||
, len = req.headers['content-length']
|
||||
? parseInt(req.headers['content-length'], 10)
|
||||
: null;
|
||||
|
||||
// self-awareness
|
||||
if (req._limit) return next();
|
||||
req._limit = true;
|
||||
|
||||
// limit by content-length
|
||||
if (len && len > bytes) return next(utils.error(413));
|
||||
|
||||
// limit
|
||||
req.on('data', function(chunk){
|
||||
received += chunk.length;
|
||||
if (received > bytes) req.destroy();
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
339
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/logger.js
generated
vendored
Normal file
339
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/logger.js
generated
vendored
Normal file
|
@ -0,0 +1,339 @@
|
|||
/*!
|
||||
* Connect - logger
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var bytes = require('bytes');
|
||||
|
||||
/*!
|
||||
* Log buffer.
|
||||
*/
|
||||
|
||||
var buf = [];
|
||||
|
||||
/*!
|
||||
* Default log buffer duration.
|
||||
*/
|
||||
|
||||
var defaultBufferDuration = 1000;
|
||||
|
||||
/**
|
||||
* Logger:
|
||||
*
|
||||
* Log requests with the given `options` or a `format` string.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `format` Format string, see below for tokens
|
||||
* - `stream` Output stream, defaults to _stdout_
|
||||
* - `buffer` Buffer duration, defaults to 1000ms when _true_
|
||||
* - `immediate` Write log line on request instead of response (for response times)
|
||||
*
|
||||
* Tokens:
|
||||
*
|
||||
* - `:req[header]` ex: `:req[Accept]`
|
||||
* - `:res[header]` ex: `:res[Content-Length]`
|
||||
* - `:http-version`
|
||||
* - `:response-time`
|
||||
* - `:remote-addr`
|
||||
* - `:date`
|
||||
* - `:method`
|
||||
* - `:url`
|
||||
* - `:referrer`
|
||||
* - `:user-agent`
|
||||
* - `:status`
|
||||
*
|
||||
* Formats:
|
||||
*
|
||||
* Pre-defined formats that ship with connect:
|
||||
*
|
||||
* - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'
|
||||
* - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'
|
||||
* - `tiny` ':method :url :status :res[content-length] - :response-time ms'
|
||||
* - `dev` concise output colored by response status for development use
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* connect.logger() // default
|
||||
* connect.logger('short')
|
||||
* connect.logger('tiny')
|
||||
* connect.logger({ immediate: true, format: 'dev' })
|
||||
* connect.logger(':method :url - :referrer')
|
||||
* connect.logger(':req[content-type] -> :res[content-type]')
|
||||
* connect.logger(function(tokens, req, res){ return 'some format string' })
|
||||
*
|
||||
* Defining Tokens:
|
||||
*
|
||||
* To define a token, simply invoke `connect.logger.token()` with the
|
||||
* name and a callback function. The value returned is then available
|
||||
* as ":type" in this case.
|
||||
*
|
||||
* connect.logger.token('type', function(req, res){ return req.headers['content-type']; })
|
||||
*
|
||||
* Defining Formats:
|
||||
*
|
||||
* All default formats are defined this way, however it's public API as well:
|
||||
*
|
||||
* connect.logger.format('name', 'string or function')
|
||||
*
|
||||
* @param {String|Function|Object} format or options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function logger(options) {
|
||||
if ('object' == typeof options) {
|
||||
options = options || {};
|
||||
} else if (options) {
|
||||
options = { format: options };
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
|
||||
// output on request instead of response
|
||||
var immediate = options.immediate;
|
||||
|
||||
// format name
|
||||
var fmt = exports[options.format] || options.format || exports.default;
|
||||
|
||||
// compile format
|
||||
if ('function' != typeof fmt) fmt = compile(fmt);
|
||||
|
||||
// options
|
||||
var stream = options.stream || process.stdout
|
||||
, buffer = options.buffer;
|
||||
|
||||
// buffering support
|
||||
if (buffer) {
|
||||
var realStream = stream
|
||||
, interval = 'number' == typeof buffer
|
||||
? buffer
|
||||
: defaultBufferDuration;
|
||||
|
||||
// flush interval
|
||||
setInterval(function(){
|
||||
if (buf.length) {
|
||||
realStream.write(buf.join(''));
|
||||
buf.length = 0;
|
||||
}
|
||||
}, interval);
|
||||
|
||||
// swap the stream
|
||||
stream = {
|
||||
write: function(str){
|
||||
buf.push(str);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return function logger(req, res, next) {
|
||||
req._startTime = new Date;
|
||||
|
||||
// immediate
|
||||
if (immediate) {
|
||||
var line = fmt(exports, req, res);
|
||||
if (null == line) return;
|
||||
stream.write(line + '\n');
|
||||
// proxy end to output logging
|
||||
} else {
|
||||
var end = res.end;
|
||||
res.end = function(chunk, encoding){
|
||||
res.end = end;
|
||||
res.end(chunk, encoding);
|
||||
var line = fmt(exports, req, res);
|
||||
if (null == line) return;
|
||||
stream.write(line + '\n');
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Compile `fmt` into a function.
|
||||
*
|
||||
* @param {String} fmt
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function compile(fmt) {
|
||||
fmt = fmt.replace(/"/g, '\\"');
|
||||
var js = ' return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function(_, name, arg){
|
||||
return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "';
|
||||
}) + '";'
|
||||
return new Function('tokens, req, res', js);
|
||||
};
|
||||
|
||||
/**
|
||||
* Define a token function with the given `name`,
|
||||
* and callback `fn(req, res)`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Function} fn
|
||||
* @return {Object} exports for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.token = function(name, fn) {
|
||||
exports[name] = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Define a `fmt` with the given `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String|Function} fmt
|
||||
* @return {Object} exports for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.format = function(name, str){
|
||||
exports[name] = str;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default format.
|
||||
*/
|
||||
|
||||
exports.format('default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"');
|
||||
|
||||
/**
|
||||
* Short format.
|
||||
*/
|
||||
|
||||
exports.format('short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms');
|
||||
|
||||
/**
|
||||
* Tiny format.
|
||||
*/
|
||||
|
||||
exports.format('tiny', ':method :url :status :res[content-length] - :response-time ms');
|
||||
|
||||
/**
|
||||
* dev (colored)
|
||||
*/
|
||||
|
||||
exports.format('dev', function(tokens, req, res){
|
||||
var status = res.statusCode
|
||||
, len = parseInt(res.getHeader('Content-Length'), 10)
|
||||
, color = 32;
|
||||
|
||||
if (status >= 500) color = 31
|
||||
else if (status >= 400) color = 33
|
||||
else if (status >= 300) color = 36;
|
||||
|
||||
len = isNaN(len)
|
||||
? ''
|
||||
: len = ' - ' + bytes(len);
|
||||
|
||||
return '\033[90m' + req.method
|
||||
+ ' ' + req.originalUrl + ' '
|
||||
+ '\033[' + color + 'm' + res.statusCode
|
||||
+ ' \033[90m'
|
||||
+ (new Date - req._startTime)
|
||||
+ 'ms' + len
|
||||
+ '\033[0m';
|
||||
});
|
||||
|
||||
/**
|
||||
* request url
|
||||
*/
|
||||
|
||||
exports.token('url', function(req){
|
||||
return req.originalUrl || req.url;
|
||||
});
|
||||
|
||||
/**
|
||||
* request method
|
||||
*/
|
||||
|
||||
exports.token('method', function(req){
|
||||
return req.method;
|
||||
});
|
||||
|
||||
/**
|
||||
* response time in milliseconds
|
||||
*/
|
||||
|
||||
exports.token('response-time', function(req){
|
||||
return new Date - req._startTime;
|
||||
});
|
||||
|
||||
/**
|
||||
* UTC date
|
||||
*/
|
||||
|
||||
exports.token('date', function(){
|
||||
return new Date().toUTCString();
|
||||
});
|
||||
|
||||
/**
|
||||
* response status code
|
||||
*/
|
||||
|
||||
exports.token('status', function(req, res){
|
||||
return res.statusCode;
|
||||
});
|
||||
|
||||
/**
|
||||
* normalized referrer
|
||||
*/
|
||||
|
||||
exports.token('referrer', function(req){
|
||||
return req.headers['referer'] || req.headers['referrer'];
|
||||
});
|
||||
|
||||
/**
|
||||
* remote address
|
||||
*/
|
||||
|
||||
exports.token('remote-addr', function(req){
|
||||
if (req.ip) return req.ip;
|
||||
var sock = req.socket;
|
||||
if (sock.socket) return sock.socket.remoteAddress;
|
||||
return sock.remoteAddress;
|
||||
});
|
||||
|
||||
/**
|
||||
* HTTP version
|
||||
*/
|
||||
|
||||
exports.token('http-version', function(req){
|
||||
return req.httpVersionMajor + '.' + req.httpVersionMinor;
|
||||
});
|
||||
|
||||
/**
|
||||
* UA string
|
||||
*/
|
||||
|
||||
exports.token('user-agent', function(req){
|
||||
return req.headers['user-agent'];
|
||||
});
|
||||
|
||||
/**
|
||||
* request header
|
||||
*/
|
||||
|
||||
exports.token('req', function(req, res, field){
|
||||
return req.headers[field.toLowerCase()];
|
||||
});
|
||||
|
||||
/**
|
||||
* response header
|
||||
*/
|
||||
|
||||
exports.token('res', function(req, res, field){
|
||||
return (res._headers || {})[field.toLowerCase()];
|
||||
});
|
||||
|
40
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js
generated
vendored
Normal file
40
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*!
|
||||
* Connect - methodOverride
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Method Override:
|
||||
*
|
||||
* Provides faux HTTP method support.
|
||||
*
|
||||
* Pass an optional `key` to use when checking for
|
||||
* a method override, othewise defaults to _\_method_.
|
||||
* The original method is available via `req.originalMethod`.
|
||||
*
|
||||
* @param {String} key
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function methodOverride(key){
|
||||
key = key || "_method";
|
||||
return function methodOverride(req, res, next) {
|
||||
req.originalMethod = req.originalMethod || req.method;
|
||||
|
||||
// req.body
|
||||
if (req.body && key in req.body) {
|
||||
req.method = req.body[key].toUpperCase();
|
||||
delete req.body[key];
|
||||
// check X-HTTP-Method-Override
|
||||
} else if (req.headers['x-http-method-override']) {
|
||||
req.method = req.headers['x-http-method-override'].toUpperCase();
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
133
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/multipart.js
generated
vendored
Normal file
133
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/multipart.js
generated
vendored
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*!
|
||||
* Connect - multipart
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var formidable = require('formidable')
|
||||
, _limit = require('./limit')
|
||||
, utils = require('../utils')
|
||||
, qs = require('qs');
|
||||
|
||||
/**
|
||||
* noop middleware.
|
||||
*/
|
||||
|
||||
function noop(req, res, next) {
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Multipart:
|
||||
*
|
||||
* Parse multipart/form-data request bodies,
|
||||
* providing the parsed object as `req.body`
|
||||
* and `req.files`.
|
||||
*
|
||||
* Configuration:
|
||||
*
|
||||
* The options passed are merged with [formidable](https://github.com/felixge/node-formidable)'s
|
||||
* `IncomingForm` object, allowing you to configure the upload directory,
|
||||
* size limits, etc. For example if you wish to change the upload dir do the following.
|
||||
*
|
||||
* app.use(connect.multipart({ uploadDir: path }));
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `limit` byte limit defaulting to none
|
||||
* - `defer` defers processing and exposes the Formidable form object as `req.form`.
|
||||
* `next()` is called without waiting for the form's "end" event.
|
||||
* This option is useful if you need to bind to the "progress" event, for example.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function(options){
|
||||
options = options || {};
|
||||
|
||||
var limit = options.limit
|
||||
? _limit(options.limit)
|
||||
: noop;
|
||||
|
||||
return function multipart(req, res, next) {
|
||||
if (req._body) return next();
|
||||
req.body = req.body || {};
|
||||
req.files = req.files || {};
|
||||
|
||||
if (!utils.hasBody(req)) return next();
|
||||
|
||||
// ignore GET
|
||||
if ('GET' == req.method || 'HEAD' == req.method) return next();
|
||||
|
||||
// check Content-Type
|
||||
if ('multipart/form-data' != utils.mime(req)) return next();
|
||||
|
||||
// flag as parsed
|
||||
req._body = true;
|
||||
|
||||
// parse
|
||||
limit(req, res, function(err){
|
||||
if (err) return next(err);
|
||||
|
||||
var form = new formidable.IncomingForm
|
||||
, data = {}
|
||||
, files = {}
|
||||
, done;
|
||||
|
||||
Object.keys(options).forEach(function(key){
|
||||
form[key] = options[key];
|
||||
});
|
||||
|
||||
function ondata(name, val, data){
|
||||
if (Array.isArray(data[name])) {
|
||||
data[name].push(val);
|
||||
} else if (data[name]) {
|
||||
data[name] = [data[name], val];
|
||||
} else {
|
||||
data[name] = val;
|
||||
}
|
||||
}
|
||||
|
||||
form.on('field', function(name, val){
|
||||
ondata(name, val, data);
|
||||
});
|
||||
|
||||
form.on('file', function(name, val){
|
||||
ondata(name, val, files);
|
||||
});
|
||||
|
||||
form.on('error', function(err){
|
||||
if (!options.defer) {
|
||||
err.status = 400;
|
||||
next(err);
|
||||
}
|
||||
done = true;
|
||||
});
|
||||
|
||||
form.on('end', function(){
|
||||
if (done) return;
|
||||
try {
|
||||
req.body = qs.parse(data);
|
||||
req.files = qs.parse(files);
|
||||
if (!options.defer) next();
|
||||
} catch (err) {
|
||||
form.emit('error', err);
|
||||
}
|
||||
});
|
||||
|
||||
form.parse(req);
|
||||
|
||||
if (options.defer) {
|
||||
req.form = form;
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
46
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/query.js
generated
vendored
Normal file
46
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/query.js
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*!
|
||||
* Connect - query
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var qs = require('qs')
|
||||
, parse = require('../utils').parseUrl;
|
||||
|
||||
/**
|
||||
* Query:
|
||||
*
|
||||
* Automatically parse the query-string when available,
|
||||
* populating the `req.query` object.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.query())
|
||||
* .use(function(req, res){
|
||||
* res.end(JSON.stringify(req.query));
|
||||
* });
|
||||
*
|
||||
* The `options` passed are provided to qs.parse function.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function query(options){
|
||||
return function query(req, res, next){
|
||||
if (!req.query) {
|
||||
req.query = ~req.url.indexOf('?')
|
||||
? qs.parse(parse(req).query, options)
|
||||
: {};
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
32
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/responseTime.js
generated
vendored
Normal file
32
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/responseTime.js
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
/*!
|
||||
* Connect - responseTime
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reponse time:
|
||||
*
|
||||
* Adds the `X-Response-Time` header displaying the response
|
||||
* duration in milliseconds.
|
||||
*
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function responseTime(){
|
||||
return function(req, res, next){
|
||||
var start = new Date;
|
||||
|
||||
if (res._responseTime) return next();
|
||||
res._responseTime = true;
|
||||
|
||||
res.on('header', function(){
|
||||
var duration = new Date - start;
|
||||
res.setHeader('X-Response-Time', duration + 'ms');
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
352
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session.js
generated
vendored
Normal file
352
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session.js
generated
vendored
Normal file
|
@ -0,0 +1,352 @@
|
|||
|
||||
/*!
|
||||
* Connect - session
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Session = require('./session/session')
|
||||
, debug = require('debug')('connect:session')
|
||||
, MemoryStore = require('./session/memory')
|
||||
, signature = require('cookie-signature')
|
||||
, Cookie = require('./session/cookie')
|
||||
, Store = require('./session/store')
|
||||
, utils = require('./../utils')
|
||||
, parse = utils.parseUrl
|
||||
, crc16 = require('crc').crc16;
|
||||
|
||||
// environment
|
||||
|
||||
var env = process.env.NODE_ENV;
|
||||
|
||||
/**
|
||||
* Expose the middleware.
|
||||
*/
|
||||
|
||||
exports = module.exports = session;
|
||||
|
||||
/**
|
||||
* Expose constructors.
|
||||
*/
|
||||
|
||||
exports.Store = Store;
|
||||
exports.Cookie = Cookie;
|
||||
exports.Session = Session;
|
||||
exports.MemoryStore = MemoryStore;
|
||||
|
||||
/**
|
||||
* Warning message for `MemoryStore` usage in production.
|
||||
*/
|
||||
|
||||
var warning = 'Warning: connection.session() MemoryStore is not\n'
|
||||
+ 'designed for a production environment, as it will leak\n'
|
||||
+ 'memory, and will not scale past a single process.';
|
||||
|
||||
/**
|
||||
* Session:
|
||||
*
|
||||
* Setup session store with the given `options`.
|
||||
*
|
||||
* Session data is _not_ saved in the cookie itself, however
|
||||
* cookies are used, so we must use the [cookieParser()](cookieParser.html)
|
||||
* middleware _before_ `session()`.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.cookieParser())
|
||||
* .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }}))
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `key` cookie name defaulting to `connect.sid`
|
||||
* - `store` session store instance
|
||||
* - `secret` session cookie is signed with this secret to prevent tampering
|
||||
* - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`
|
||||
* - `proxy` trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")
|
||||
*
|
||||
* Cookie option:
|
||||
*
|
||||
* By default `cookie.maxAge` is `null`, meaning no "expires" parameter is set
|
||||
* so the cookie becomes a browser-session cookie. When the user closes the
|
||||
* browser the cookie (and session) will be removed.
|
||||
*
|
||||
* ## req.session
|
||||
*
|
||||
* To store or access session data, simply use the request property `req.session`,
|
||||
* which is (generally) serialized as JSON by the store, so nested objects
|
||||
* are typically fine. For example below is a user-specific view counter:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.favicon())
|
||||
* .use(connect.cookieParser())
|
||||
* .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
|
||||
* .use(function(req, res, next){
|
||||
* var sess = req.session;
|
||||
* if (sess.views) {
|
||||
* res.setHeader('Content-Type', 'text/html');
|
||||
* res.write('<p>views: ' + sess.views + '</p>');
|
||||
* res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
|
||||
* res.end();
|
||||
* sess.views++;
|
||||
* } else {
|
||||
* sess.views = 1;
|
||||
* res.end('welcome to the session demo. refresh!');
|
||||
* }
|
||||
* }
|
||||
* )).listen(3000);
|
||||
*
|
||||
* ## Session#regenerate()
|
||||
*
|
||||
* To regenerate the session simply invoke the method, once complete
|
||||
* a new SID and `Session` instance will be initialized at `req.session`.
|
||||
*
|
||||
* req.session.regenerate(function(err){
|
||||
* // will have a new session here
|
||||
* });
|
||||
*
|
||||
* ## Session#destroy()
|
||||
*
|
||||
* Destroys the session, removing `req.session`, will be re-generated next request.
|
||||
*
|
||||
* req.session.destroy(function(err){
|
||||
* // cannot access session here
|
||||
* });
|
||||
*
|
||||
* ## Session#reload()
|
||||
*
|
||||
* Reloads the session data.
|
||||
*
|
||||
* req.session.reload(function(err){
|
||||
* // session updated
|
||||
* });
|
||||
*
|
||||
* ## Session#save()
|
||||
*
|
||||
* Save the session.
|
||||
*
|
||||
* req.session.save(function(err){
|
||||
* // session saved
|
||||
* });
|
||||
*
|
||||
* ## Session#touch()
|
||||
*
|
||||
* Updates the `.maxAge` property. Typically this is
|
||||
* not necessary to call, as the session middleware does this for you.
|
||||
*
|
||||
* ## Session#cookie
|
||||
*
|
||||
* Each session has a unique cookie object accompany it. This allows
|
||||
* you to alter the session cookie per visitor. For example we can
|
||||
* set `req.session.cookie.expires` to `false` to enable the cookie
|
||||
* to remain for only the duration of the user-agent.
|
||||
*
|
||||
* ## Session#maxAge
|
||||
*
|
||||
* Alternatively `req.session.cookie.maxAge` will return the time
|
||||
* remaining in milliseconds, which we may also re-assign a new value
|
||||
* to adjust the `.expires` property appropriately. The following
|
||||
* are essentially equivalent
|
||||
*
|
||||
* var hour = 3600000;
|
||||
* req.session.cookie.expires = new Date(Date.now() + hour);
|
||||
* req.session.cookie.maxAge = hour;
|
||||
*
|
||||
* For example when `maxAge` is set to `60000` (one minute), and 30 seconds
|
||||
* has elapsed it will return `30000` until the current request has completed,
|
||||
* at which time `req.session.touch()` is called to reset `req.session.maxAge`
|
||||
* to its original value.
|
||||
*
|
||||
* req.session.cookie.maxAge;
|
||||
* // => 30000
|
||||
*
|
||||
* Session Store Implementation:
|
||||
*
|
||||
* Every session store _must_ implement the following methods
|
||||
*
|
||||
* - `.get(sid, callback)`
|
||||
* - `.set(sid, session, callback)`
|
||||
* - `.destroy(sid, callback)`
|
||||
*
|
||||
* Recommended methods include, but are not limited to:
|
||||
*
|
||||
* - `.length(callback)`
|
||||
* - `.clear(callback)`
|
||||
*
|
||||
* For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function session(options){
|
||||
var options = options || {}
|
||||
, key = options.key || 'connect.sid'
|
||||
, store = options.store || new MemoryStore
|
||||
, cookie = options.cookie || {}
|
||||
, trustProxy = options.proxy
|
||||
, storeReady = true;
|
||||
|
||||
// notify user that this store is not
|
||||
// meant for a production environment
|
||||
if ('production' == env && store instanceof MemoryStore) {
|
||||
console.warn(warning);
|
||||
}
|
||||
|
||||
// generates the new session
|
||||
store.generate = function(req){
|
||||
req.sessionID = utils.uid(24);
|
||||
req.session = new Session(req);
|
||||
req.session.cookie = new Cookie(cookie);
|
||||
};
|
||||
|
||||
store.on('disconnect', function(){ storeReady = false; });
|
||||
store.on('connect', function(){ storeReady = true; });
|
||||
|
||||
return function session(req, res, next) {
|
||||
// self-awareness
|
||||
if (req.session) return next();
|
||||
|
||||
// Handle connection as if there is no session if
|
||||
// the store has temporarily disconnected etc
|
||||
if (!storeReady) return debug('store is disconnected'), next();
|
||||
|
||||
// pathname mismatch
|
||||
if (0 != req.originalUrl.indexOf(cookie.path || '/')) return next();
|
||||
|
||||
// backwards compatibility for signed cookies
|
||||
// req.secret is passed from the cookie parser middleware
|
||||
var secret = options.secret || req.secret;
|
||||
|
||||
// ensure secret is available or bail
|
||||
if (!secret) throw new Error('`secret` option required for sessions');
|
||||
|
||||
// parse url
|
||||
var originalHash
|
||||
, originalId;
|
||||
|
||||
// expose store
|
||||
req.sessionStore = store;
|
||||
|
||||
// grab the session cookie value and check the signature
|
||||
var rawCookie = req.cookies[key];
|
||||
|
||||
// get signedCookies for backwards compat with signed cookies
|
||||
var unsignedCookie = req.signedCookies[key];
|
||||
|
||||
if (!unsignedCookie && rawCookie) {
|
||||
unsignedCookie = utils.parseSignedCookie(rawCookie, secret);
|
||||
}
|
||||
|
||||
// set-cookie
|
||||
res.on('header', function(){
|
||||
if (!req.session) return;
|
||||
var cookie = req.session.cookie
|
||||
, proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
|
||||
, tls = req.connection.encrypted || (trustProxy && 'https' == proto)
|
||||
, secured = cookie.secure && tls
|
||||
, isNew = unsignedCookie != req.sessionID;
|
||||
|
||||
// only send secure cookies via https
|
||||
if (cookie.secure && !secured) return debug('not secured');
|
||||
|
||||
// browser-session length cookie
|
||||
if (null == cookie.expires) {
|
||||
if (!isNew) return debug('already set browser-session cookie');
|
||||
// compare hashes and ids
|
||||
} else if (originalHash == hash(req.session) && originalId == req.session.id) {
|
||||
return debug('unmodified session');
|
||||
}
|
||||
|
||||
var val = 's:' + signature.sign(req.sessionID, secret);
|
||||
val = cookie.serialize(key, val);
|
||||
debug('set-cookie %s', val);
|
||||
res.setHeader('Set-Cookie', val);
|
||||
});
|
||||
|
||||
// proxy end() to commit the session
|
||||
var end = res.end;
|
||||
res.end = function(data, encoding){
|
||||
res.end = end;
|
||||
if (!req.session) return res.end(data, encoding);
|
||||
debug('saving');
|
||||
req.session.resetMaxAge();
|
||||
req.session.save(function(){
|
||||
debug('saved');
|
||||
res.end(data, encoding);
|
||||
});
|
||||
};
|
||||
|
||||
// generate the session
|
||||
function generate() {
|
||||
store.generate(req);
|
||||
}
|
||||
|
||||
// get the sessionID from the cookie
|
||||
req.sessionID = unsignedCookie;
|
||||
|
||||
// generate a session if the browser doesn't send a sessionID
|
||||
if (!req.sessionID) {
|
||||
debug('no SID sent, generating session');
|
||||
generate();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// generate the session object
|
||||
var pause = utils.pause(req);
|
||||
debug('fetching %s', req.sessionID);
|
||||
store.get(req.sessionID, function(err, sess){
|
||||
// proxy to resume() events
|
||||
var _next = next;
|
||||
next = function(err){
|
||||
_next(err);
|
||||
pause.resume();
|
||||
};
|
||||
|
||||
// error handling
|
||||
if (err) {
|
||||
debug('error');
|
||||
if ('ENOENT' == err.code) {
|
||||
generate();
|
||||
next();
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
// no session
|
||||
} else if (!sess) {
|
||||
debug('no session found');
|
||||
generate();
|
||||
next();
|
||||
// populate req.session
|
||||
} else {
|
||||
debug('session found');
|
||||
store.createSession(req, sess);
|
||||
originalId = req.sessionID;
|
||||
originalHash = hash(sess);
|
||||
next();
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash the given `sess` object omitting changes
|
||||
* to `.cookie`.
|
||||
*
|
||||
* @param {Object} sess
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function hash(sess) {
|
||||
return crc16(JSON.stringify(sess, function(key, val){
|
||||
if ('cookie' != key) return val;
|
||||
}));
|
||||
}
|
128
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js
generated
vendored
Normal file
128
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
|
||||
/*!
|
||||
* Connect - session - Cookie
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../../utils')
|
||||
, cookie = require('cookie');
|
||||
|
||||
/**
|
||||
* Initialize a new `Cookie` with the given `options`.
|
||||
*
|
||||
* @param {IncomingMessage} req
|
||||
* @param {Object} options
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var Cookie = module.exports = function Cookie(options) {
|
||||
this.path = '/';
|
||||
this.maxAge = null;
|
||||
this.httpOnly = true;
|
||||
if (options) utils.merge(this, options);
|
||||
this.originalMaxAge = undefined == this.originalMaxAge
|
||||
? this.maxAge
|
||||
: this.originalMaxAge;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Prototype.
|
||||
*/
|
||||
|
||||
Cookie.prototype = {
|
||||
|
||||
/**
|
||||
* Set expires `date`.
|
||||
*
|
||||
* @param {Date} date
|
||||
* @api public
|
||||
*/
|
||||
|
||||
set expires(date) {
|
||||
this._expires = date;
|
||||
this.originalMaxAge = this.maxAge;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get expires `date`.
|
||||
*
|
||||
* @return {Date}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
get expires() {
|
||||
return this._expires;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set expires via max-age in `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @api public
|
||||
*/
|
||||
|
||||
set maxAge(ms) {
|
||||
this.expires = 'number' == typeof ms
|
||||
? new Date(Date.now() + ms)
|
||||
: ms;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get expires max-age in `ms`.
|
||||
*
|
||||
* @return {Number}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
get maxAge() {
|
||||
return this.expires instanceof Date
|
||||
? this.expires.valueOf() - Date.now()
|
||||
: this.expires;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return cookie data object.
|
||||
*
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
get data() {
|
||||
return {
|
||||
originalMaxAge: this.originalMaxAge
|
||||
, expires: this._expires
|
||||
, secure: this.secure
|
||||
, httpOnly: this.httpOnly
|
||||
, domain: this.domain
|
||||
, path: this.path
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a serialized cookie string.
|
||||
*
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
serialize: function(name, val){
|
||||
return cookie.serialize(name, val, this.data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return JSON representation of this cookie.
|
||||
*
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
toJSON: function(){
|
||||
return this.data;
|
||||
}
|
||||
};
|
129
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session/memory.js
generated
vendored
Normal file
129
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session/memory.js
generated
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
|
||||
/*!
|
||||
* Connect - session - MemoryStore
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Store = require('./store');
|
||||
|
||||
/**
|
||||
* Initialize a new `MemoryStore`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var MemoryStore = module.exports = function MemoryStore() {
|
||||
this.sessions = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Inherit from `Store.prototype`.
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.__proto__ = Store.prototype;
|
||||
|
||||
/**
|
||||
* Attempt to fetch session by the given `sid`.
|
||||
*
|
||||
* @param {String} sid
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.get = function(sid, fn){
|
||||
var self = this;
|
||||
process.nextTick(function(){
|
||||
var expires
|
||||
, sess = self.sessions[sid];
|
||||
if (sess) {
|
||||
sess = JSON.parse(sess);
|
||||
expires = 'string' == typeof sess.cookie.expires
|
||||
? new Date(sess.cookie.expires)
|
||||
: sess.cookie.expires;
|
||||
if (!expires || new Date < expires) {
|
||||
fn(null, sess);
|
||||
} else {
|
||||
self.destroy(sid, fn);
|
||||
}
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Commit the given `sess` object associated with the given `sid`.
|
||||
*
|
||||
* @param {String} sid
|
||||
* @param {Session} sess
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.set = function(sid, sess, fn){
|
||||
var self = this;
|
||||
process.nextTick(function(){
|
||||
self.sessions[sid] = JSON.stringify(sess);
|
||||
fn && fn();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the session associated with the given `sid`.
|
||||
*
|
||||
* @param {String} sid
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.destroy = function(sid, fn){
|
||||
var self = this;
|
||||
process.nextTick(function(){
|
||||
delete self.sessions[sid];
|
||||
fn && fn();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Invoke the given callback `fn` with all active sessions.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.all = function(fn){
|
||||
var arr = []
|
||||
, keys = Object.keys(this.sessions);
|
||||
for (var i = 0, len = keys.length; i < len; ++i) {
|
||||
arr.push(this.sessions[keys[i]]);
|
||||
}
|
||||
fn(null, arr);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear all sessions.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.clear = function(fn){
|
||||
this.sessions = {};
|
||||
fn && fn();
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch number of sessions.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MemoryStore.prototype.length = function(fn){
|
||||
fn(null, Object.keys(this.sessions).length);
|
||||
};
|
116
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session/session.js
generated
vendored
Normal file
116
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session/session.js
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
|
||||
/*!
|
||||
* Connect - session - Session
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../../utils');
|
||||
|
||||
/**
|
||||
* Create a new `Session` with the given request and `data`.
|
||||
*
|
||||
* @param {IncomingRequest} req
|
||||
* @param {Object} data
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var Session = module.exports = function Session(req, data) {
|
||||
Object.defineProperty(this, 'req', { value: req });
|
||||
Object.defineProperty(this, 'id', { value: req.sessionID });
|
||||
if ('object' == typeof data) utils.merge(this, data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update reset `.cookie.maxAge` to prevent
|
||||
* the cookie from expiring when the
|
||||
* session is still active.
|
||||
*
|
||||
* @return {Session} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Session.prototype.touch = function(){
|
||||
return this.resetMaxAge();
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset `.maxAge` to `.originalMaxAge`.
|
||||
*
|
||||
* @return {Session} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Session.prototype.resetMaxAge = function(){
|
||||
this.cookie.maxAge = this.cookie.originalMaxAge;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Save the session data with optional callback `fn(err)`.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Session} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Session.prototype.save = function(fn){
|
||||
this.req.sessionStore.set(this.id, this, fn || function(){});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Re-loads the session data _without_ altering
|
||||
* the maxAge properties. Invokes the callback `fn(err)`,
|
||||
* after which time if no exception has occurred the
|
||||
* `req.session` property will be a new `Session` object,
|
||||
* although representing the same session.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Session} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Session.prototype.reload = function(fn){
|
||||
var req = this.req
|
||||
, store = this.req.sessionStore;
|
||||
store.get(this.id, function(err, sess){
|
||||
if (err) return fn(err);
|
||||
if (!sess) return fn(new Error('failed to load session'));
|
||||
store.createSession(req, sess);
|
||||
fn();
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy `this` session.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Session} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Session.prototype.destroy = function(fn){
|
||||
delete this.req.session;
|
||||
this.req.sessionStore.destroy(this.id, fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Regenerate this request's session.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Session} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Session.prototype.regenerate = function(fn){
|
||||
this.req.sessionStore.regenerate(this.req, fn);
|
||||
return this;
|
||||
};
|
84
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session/store.js
generated
vendored
Normal file
84
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/session/store.js
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
|
||||
/*!
|
||||
* Connect - session - Store
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
, Session = require('./session')
|
||||
, Cookie = require('./cookie');
|
||||
|
||||
/**
|
||||
* Initialize abstract `Store`.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var Store = module.exports = function Store(options){};
|
||||
|
||||
/**
|
||||
* Inherit from `EventEmitter.prototype`.
|
||||
*/
|
||||
|
||||
Store.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
/**
|
||||
* Re-generate the given requests's session.
|
||||
*
|
||||
* @param {IncomingRequest} req
|
||||
* @return {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Store.prototype.regenerate = function(req, fn){
|
||||
var self = this;
|
||||
this.destroy(req.sessionID, function(err){
|
||||
self.generate(req);
|
||||
fn(err);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a `Session` instance via the given `sid`
|
||||
* and invoke the callback `fn(err, sess)`.
|
||||
*
|
||||
* @param {String} sid
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Store.prototype.load = function(sid, fn){
|
||||
var self = this;
|
||||
this.get(sid, function(err, sess){
|
||||
if (err) return fn(err);
|
||||
if (!sess) return fn();
|
||||
var req = { sessionID: sid, sessionStore: self };
|
||||
sess = self.createSession(req, sess);
|
||||
fn(null, sess);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create session from JSON `sess` data.
|
||||
*
|
||||
* @param {IncomingRequest} req
|
||||
* @param {Object} sess
|
||||
* @return {Session}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Store.prototype.createSession = function(req, sess){
|
||||
var expires = sess.cookie.expires
|
||||
, orig = sess.cookie.originalMaxAge;
|
||||
sess.cookie = new Cookie(sess.cookie);
|
||||
if ('string' == typeof expires) sess.cookie.expires = new Date(expires);
|
||||
sess.cookie.originalMaxAge = orig;
|
||||
req.session = new Session(req, sess);
|
||||
return req.session;
|
||||
};
|
94
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/static.js
generated
vendored
Normal file
94
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/static.js
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
|
||||
/*!
|
||||
* Connect - static
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var send = require('send')
|
||||
, utils = require('../utils')
|
||||
, parse = utils.parseUrl
|
||||
, url = require('url');
|
||||
|
||||
/**
|
||||
* Static:
|
||||
*
|
||||
* Static file server with the given `root` path.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* var oneDay = 86400000;
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.static(__dirname + '/public'))
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.static(__dirname + '/public', { maxAge: oneDay }))
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `maxAge` Browser cache maxAge in milliseconds. defaults to 0
|
||||
* - `hidden` Allow transfer of hidden files. defaults to false
|
||||
* - `redirect` Redirect to trailing "/" when the pathname is a dir. defaults to true
|
||||
*
|
||||
* @param {String} root
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function static(root, options){
|
||||
options = options || {};
|
||||
|
||||
// root required
|
||||
if (!root) throw new Error('static() root path required');
|
||||
|
||||
// default redirect
|
||||
var redirect = false !== options.redirect;
|
||||
|
||||
return function static(req, res, next) {
|
||||
if ('GET' != req.method && 'HEAD' != req.method) return next();
|
||||
var path = parse(req).pathname;
|
||||
var pause = utils.pause(req);
|
||||
|
||||
function resume() {
|
||||
next();
|
||||
pause.resume();
|
||||
}
|
||||
|
||||
function directory() {
|
||||
if (!redirect) return resume();
|
||||
var pathname = url.parse(req.originalUrl).pathname;
|
||||
res.statusCode = 301;
|
||||
res.setHeader('Location', pathname + '/');
|
||||
res.end('Redirecting to ' + utils.escape(pathname) + '/');
|
||||
}
|
||||
|
||||
function error(err) {
|
||||
if (404 == err.status) return resume();
|
||||
next(err);
|
||||
}
|
||||
|
||||
send(req, path)
|
||||
.maxage(options.maxAge || 0)
|
||||
.root(root)
|
||||
.hidden(options.hidden)
|
||||
.on('error', error)
|
||||
.on('directory', directory)
|
||||
.pipe(res);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose mime module.
|
||||
*
|
||||
* If you wish to extend the mime table use this
|
||||
* reference to the "mime" module in the npm registry.
|
||||
*/
|
||||
|
||||
exports.mime = send.mime;
|
231
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/staticCache.js
generated
vendored
Normal file
231
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/staticCache.js
generated
vendored
Normal file
|
@ -0,0 +1,231 @@
|
|||
|
||||
/*!
|
||||
* Connect - staticCache
|
||||
* Copyright(c) 2011 Sencha Inc.
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, Cache = require('../cache')
|
||||
, fresh = require('fresh');
|
||||
|
||||
/**
|
||||
* Static cache:
|
||||
*
|
||||
* Enables a memory cache layer on top of
|
||||
* the `static()` middleware, serving popular
|
||||
* static files.
|
||||
*
|
||||
* By default a maximum of 128 objects are
|
||||
* held in cache, with a max of 256k each,
|
||||
* totalling ~32mb.
|
||||
*
|
||||
* A Least-Recently-Used (LRU) cache algo
|
||||
* is implemented through the `Cache` object,
|
||||
* simply rotating cache objects as they are
|
||||
* hit. This means that increasingly popular
|
||||
* objects maintain their positions while
|
||||
* others get shoved out of the stack and
|
||||
* garbage collected.
|
||||
*
|
||||
* Benchmarks:
|
||||
*
|
||||
* static(): 2700 rps
|
||||
* node-static: 5300 rps
|
||||
* static() + staticCache(): 7500 rps
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `maxObjects` max cache objects [128]
|
||||
* - `maxLength` max cache object length 256kb
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function staticCache(options){
|
||||
var options = options || {}
|
||||
, cache = new Cache(options.maxObjects || 128)
|
||||
, maxlen = options.maxLength || 1024 * 256;
|
||||
|
||||
console.warn('connect.staticCache() is deprecated and will be removed in 3.0');
|
||||
console.warn('use varnish or similar reverse proxy caches.');
|
||||
|
||||
return function staticCache(req, res, next){
|
||||
var key = cacheKey(req)
|
||||
, ranges = req.headers.range
|
||||
, hasCookies = req.headers.cookie
|
||||
, hit = cache.get(key);
|
||||
|
||||
// cache static
|
||||
// TODO: change from staticCache() -> cache()
|
||||
// and make this work for any request
|
||||
req.on('static', function(stream){
|
||||
var headers = res._headers
|
||||
, cc = utils.parseCacheControl(headers['cache-control'] || '')
|
||||
, contentLength = headers['content-length']
|
||||
, hit;
|
||||
|
||||
// dont cache set-cookie responses
|
||||
if (headers['set-cookie']) return hasCookies = true;
|
||||
|
||||
// dont cache when cookies are present
|
||||
if (hasCookies) return;
|
||||
|
||||
// ignore larger files
|
||||
if (!contentLength || contentLength > maxlen) return;
|
||||
|
||||
// don't cache partial files
|
||||
if (headers['content-range']) return;
|
||||
|
||||
// dont cache items we shouldn't be
|
||||
// TODO: real support for must-revalidate / no-cache
|
||||
if ( cc['no-cache']
|
||||
|| cc['no-store']
|
||||
|| cc['private']
|
||||
|| cc['must-revalidate']) return;
|
||||
|
||||
// if already in cache then validate
|
||||
if (hit = cache.get(key)){
|
||||
if (headers.etag == hit[0].etag) {
|
||||
hit[0].date = new Date;
|
||||
return;
|
||||
} else {
|
||||
cache.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
// validation notifiactions don't contain a steam
|
||||
if (null == stream) return;
|
||||
|
||||
// add the cache object
|
||||
var arr = [];
|
||||
|
||||
// store the chunks
|
||||
stream.on('data', function(chunk){
|
||||
arr.push(chunk);
|
||||
});
|
||||
|
||||
// flag it as complete
|
||||
stream.on('end', function(){
|
||||
var cacheEntry = cache.add(key);
|
||||
delete headers['x-cache']; // Clean up (TODO: others)
|
||||
cacheEntry.push(200);
|
||||
cacheEntry.push(headers);
|
||||
cacheEntry.push.apply(cacheEntry, arr);
|
||||
});
|
||||
});
|
||||
|
||||
if (req.method == 'GET' || req.method == 'HEAD') {
|
||||
if (ranges) {
|
||||
next();
|
||||
} else if (!hasCookies && hit && !mustRevalidate(req, hit)) {
|
||||
res.setHeader('X-Cache', 'HIT');
|
||||
respondFromCache(req, res, hit);
|
||||
} else {
|
||||
res.setHeader('X-Cache', 'MISS');
|
||||
next();
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Respond with the provided cached value.
|
||||
* TODO: Assume 200 code, that's iffy.
|
||||
*
|
||||
* @param {Object} req
|
||||
* @param {Object} res
|
||||
* @param {Object} cacheEntry
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function respondFromCache(req, res, cacheEntry) {
|
||||
var status = cacheEntry[0]
|
||||
, headers = utils.merge({}, cacheEntry[1])
|
||||
, content = cacheEntry.slice(2);
|
||||
|
||||
headers.age = (new Date - new Date(headers.date)) / 1000 || 0;
|
||||
|
||||
switch (req.method) {
|
||||
case 'HEAD':
|
||||
res.writeHead(status, headers);
|
||||
res.end();
|
||||
break;
|
||||
case 'GET':
|
||||
if (utils.conditionalGET(req) && fresh(req.headers, headers)) {
|
||||
headers['content-length'] = 0;
|
||||
res.writeHead(304, headers);
|
||||
res.end();
|
||||
} else {
|
||||
res.writeHead(status, headers);
|
||||
|
||||
function write() {
|
||||
while (content.length) {
|
||||
if (false === res.write(content.shift())) {
|
||||
res.once('drain', write);
|
||||
return;
|
||||
}
|
||||
}
|
||||
res.end();
|
||||
}
|
||||
|
||||
write();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// This should never happen.
|
||||
res.writeHead(500, '');
|
||||
res.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not a cached value must be revalidated.
|
||||
*
|
||||
* @param {Object} req
|
||||
* @param {Object} cacheEntry
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function mustRevalidate(req, cacheEntry) {
|
||||
var cacheHeaders = cacheEntry[1]
|
||||
, reqCC = utils.parseCacheControl(req.headers['cache-control'] || '')
|
||||
, cacheCC = utils.parseCacheControl(cacheHeaders['cache-control'] || '')
|
||||
, cacheAge = (new Date - new Date(cacheHeaders.date)) / 1000 || 0;
|
||||
|
||||
if ( cacheCC['no-cache']
|
||||
|| cacheCC['must-revalidate']
|
||||
|| cacheCC['proxy-revalidate']) return true;
|
||||
|
||||
if (reqCC['no-cache']) return true;
|
||||
|
||||
if (null != reqCC['max-age']) return reqCC['max-age'] < cacheAge;
|
||||
|
||||
if (null != cacheCC['max-age']) return cacheCC['max-age'] < cacheAge;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The key to use in the cache. For now, this is the URL path and query.
|
||||
*
|
||||
* 'http://example.com?key=value' -> '/?key=value'
|
||||
*
|
||||
* @param {Object} req
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function cacheKey(req) {
|
||||
return utils.parseUrl(req).path;
|
||||
}
|
56
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/timeout.js
generated
vendored
Normal file
56
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/timeout.js
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
|
||||
/*!
|
||||
* Connect - timeout
|
||||
* Ported from https://github.com/LearnBoost/connect-timeout
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var debug = require('debug')('connect:timeout');
|
||||
|
||||
/**
|
||||
* Timeout:
|
||||
*
|
||||
* Times out the request in `ms`, defaulting to `5000`. The
|
||||
* method `req.clearTimeout()` is added to revert this behaviour
|
||||
* programmatically within your application's middleware, routes, etc.
|
||||
*
|
||||
* The timeout error is passed to `next()` so that you may customize
|
||||
* the response behaviour. This error has the `.timeout` property as
|
||||
* well as `.status == 408`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function timeout(ms) {
|
||||
ms = ms || 5000;
|
||||
|
||||
return function(req, res, next) {
|
||||
var id = setTimeout(function(){
|
||||
req.emit('timeout', ms);
|
||||
}, ms);
|
||||
|
||||
req.on('timeout', function(){
|
||||
if (req.headerSent) return debug('response started, cannot timeout');
|
||||
var err = new Error('Request timeout');
|
||||
err.timeout = ms;
|
||||
err.status = 408;
|
||||
next(err);
|
||||
});
|
||||
|
||||
req.clearTimeout = function(){
|
||||
clearTimeout(id);
|
||||
};
|
||||
|
||||
res.on('header', function(){
|
||||
clearTimeout(id);
|
||||
});
|
||||
|
||||
next();
|
||||
};
|
||||
};
|
78
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js
generated
vendored
Normal file
78
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
|
||||
/*!
|
||||
* Connect - urlencoded
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils')
|
||||
, _limit = require('./limit')
|
||||
, qs = require('qs');
|
||||
|
||||
/**
|
||||
* noop middleware.
|
||||
*/
|
||||
|
||||
function noop(req, res, next) {
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Urlencoded:
|
||||
*
|
||||
* Parse x-ww-form-urlencoded request bodies,
|
||||
* providing the parsed object as `req.body`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `limit` byte limit disabled by default
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports = module.exports = function(options){
|
||||
options = options || {};
|
||||
|
||||
var limit = options.limit
|
||||
? _limit(options.limit)
|
||||
: noop;
|
||||
|
||||
return function urlencoded(req, res, next) {
|
||||
if (req._body) return next();
|
||||
req.body = req.body || {};
|
||||
|
||||
if (!utils.hasBody(req)) return next();
|
||||
|
||||
// check Content-Type
|
||||
if ('application/x-www-form-urlencoded' != utils.mime(req)) return next();
|
||||
|
||||
// flag as parsed
|
||||
req._body = true;
|
||||
|
||||
// parse
|
||||
limit(req, res, function(err){
|
||||
if (err) return next(err);
|
||||
var buf = '';
|
||||
req.setEncoding('utf8');
|
||||
req.on('data', function(chunk){ buf += chunk });
|
||||
req.on('end', function(){
|
||||
try {
|
||||
req.body = buf.length
|
||||
? qs.parse(buf, options)
|
||||
: {};
|
||||
next();
|
||||
} catch (err){
|
||||
err.body = buf;
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
40
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/vhost.js
generated
vendored
Normal file
40
nodeartnet/node_modules/express/node_modules/connect/lib/middleware/vhost.js
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
/*!
|
||||
* Connect - vhost
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Vhost:
|
||||
*
|
||||
* Setup vhost for the given `hostname` and `server`.
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.vhost('foo.com', fooApp))
|
||||
* .use(connect.vhost('bar.com', barApp))
|
||||
* .use(connect.vhost('*.com', mainApp))
|
||||
*
|
||||
* The `server` may be a Connect server or
|
||||
* a regular Node `http.Server`.
|
||||
*
|
||||
* @param {String} hostname
|
||||
* @param {Server} server
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function vhost(hostname, server){
|
||||
if (!hostname) throw new Error('vhost hostname required');
|
||||
if (!server) throw new Error('vhost server required');
|
||||
var regexp = new RegExp('^' + hostname.replace(/[*]/g, '(.*?)') + '$', 'i');
|
||||
if (server.onvhost) server.onvhost(hostname);
|
||||
return function vhost(req, res, next){
|
||||
if (!req.headers.host) return next();
|
||||
var host = req.headers.host.split(':')[0];
|
||||
if (!regexp.test(host)) return next();
|
||||
if ('function' == typeof server) return server(req, res, next);
|
||||
server.emit('request', req, res);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,79 @@
|
|||
|
||||
/*!
|
||||
* Connect
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http')
|
||||
, res = http.ServerResponse.prototype
|
||||
, setHeader = res.setHeader
|
||||
, _renderHeaders = res._renderHeaders
|
||||
, writeHead = res.writeHead;
|
||||
|
||||
// apply only once
|
||||
|
||||
if (!res._hasConnectPatch) {
|
||||
|
||||
/**
|
||||
* Provide a public "header sent" flag
|
||||
* until node does.
|
||||
*
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.__defineGetter__('headerSent', function(){
|
||||
return this._header;
|
||||
});
|
||||
|
||||
/**
|
||||
* Set header `field` to `val`, special-casing
|
||||
* the `Set-Cookie` field for multiple support.
|
||||
*
|
||||
* @param {String} field
|
||||
* @param {String} val
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.setHeader = function(field, val){
|
||||
var key = field.toLowerCase()
|
||||
, prev;
|
||||
|
||||
// special-case Set-Cookie
|
||||
if (this._headers && 'set-cookie' == key) {
|
||||
if (prev = this.getHeader(field)) {
|
||||
val = Array.isArray(prev)
|
||||
? prev.concat(val)
|
||||
: [prev, val];
|
||||
}
|
||||
// charset
|
||||
} else if ('content-type' == key && this.charset) {
|
||||
val += '; charset=' + this.charset;
|
||||
}
|
||||
|
||||
return setHeader.call(this, field, val);
|
||||
};
|
||||
|
||||
/**
|
||||
* Proxy to emit "header" event.
|
||||
*/
|
||||
|
||||
res._renderHeaders = function(){
|
||||
if (!this._emittedHeader) this.emit('header');
|
||||
this._emittedHeader = true;
|
||||
return _renderHeaders.call(this);
|
||||
};
|
||||
|
||||
res.writeHead = function(){
|
||||
if (!this._emittedHeader) this.emit('header');
|
||||
this._emittedHeader = true;
|
||||
return writeHead.apply(this, arguments);
|
||||
};
|
||||
|
||||
res._hasConnectPatch = true;
|
||||
}
|
230
nodeartnet/node_modules/express/node_modules/connect/lib/proto.js
generated
vendored
Normal file
230
nodeartnet/node_modules/express/node_modules/connect/lib/proto.js
generated
vendored
Normal file
|
@ -0,0 +1,230 @@
|
|||
|
||||
/*!
|
||||
* Connect - HTTPServer
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var http = require('http')
|
||||
, utils = require('./utils')
|
||||
, debug = require('debug')('connect:dispatcher');
|
||||
|
||||
// prototype
|
||||
|
||||
var app = module.exports = {};
|
||||
|
||||
// environment
|
||||
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
/**
|
||||
* Utilize the given middleware `handle` to the given `route`,
|
||||
* defaulting to _/_. This "route" is the mount-point for the
|
||||
* middleware, when given a value other than _/_ the middleware
|
||||
* is only effective when that segment is present in the request's
|
||||
* pathname.
|
||||
*
|
||||
* For example if we were to mount a function at _/admin_, it would
|
||||
* be invoked on _/admin_, and _/admin/settings_, however it would
|
||||
* not be invoked for _/_, or _/posts_.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* var app = connect();
|
||||
* app.use(connect.favicon());
|
||||
* app.use(connect.logger());
|
||||
* app.use(connect.static(__dirname + '/public'));
|
||||
*
|
||||
* If we wanted to prefix static files with _/public_, we could
|
||||
* "mount" the `static()` middleware:
|
||||
*
|
||||
* app.use('/public', connect.static(__dirname + '/public'));
|
||||
*
|
||||
* This api is chainable, so the following is valid:
|
||||
*
|
||||
* connect()
|
||||
* .use(connect.favicon())
|
||||
* .use(connect.logger())
|
||||
* .use(connect.static(__dirname + '/public'))
|
||||
* .listen(3000);
|
||||
*
|
||||
* @param {String|Function|Server} route, callback or server
|
||||
* @param {Function|Server} callback or server
|
||||
* @return {Server} for chaining
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.use = function(route, fn){
|
||||
// default route to '/'
|
||||
if ('string' != typeof route) {
|
||||
fn = route;
|
||||
route = '/';
|
||||
}
|
||||
|
||||
// wrap sub-apps
|
||||
if ('function' == typeof fn.handle) {
|
||||
var server = fn;
|
||||
fn.route = route;
|
||||
fn = function(req, res, next){
|
||||
server.handle(req, res, next);
|
||||
};
|
||||
}
|
||||
|
||||
// wrap vanilla http.Servers
|
||||
if (fn instanceof http.Server) {
|
||||
fn = fn.listeners('request')[0];
|
||||
}
|
||||
|
||||
// strip trailing slash
|
||||
if ('/' == route[route.length - 1]) {
|
||||
route = route.slice(0, -1);
|
||||
}
|
||||
|
||||
// add the middleware
|
||||
debug('use %s %s', route || '/', fn.name || 'anonymous');
|
||||
this.stack.push({ route: route, handle: fn });
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle server requests, punting them down
|
||||
* the middleware stack.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
app.handle = function(req, res, out) {
|
||||
var stack = this.stack
|
||||
, fqdn = ~req.url.indexOf('://')
|
||||
, removed = ''
|
||||
, slashAdded = false
|
||||
, index = 0;
|
||||
|
||||
function next(err) {
|
||||
var layer, path, status, c;
|
||||
|
||||
if (slashAdded) {
|
||||
req.url = req.url.substr(1);
|
||||
slashAdded = false;
|
||||
}
|
||||
|
||||
req.url = removed + req.url;
|
||||
req.originalUrl = req.originalUrl || req.url;
|
||||
removed = '';
|
||||
|
||||
// next callback
|
||||
layer = stack[index++];
|
||||
|
||||
// all done
|
||||
if (!layer || res.headerSent) {
|
||||
// delegate to parent
|
||||
if (out) return out(err);
|
||||
|
||||
// unhandled error
|
||||
if (err) {
|
||||
// default to 500
|
||||
if (res.statusCode < 400) res.statusCode = 500;
|
||||
debug('default %s', res.statusCode);
|
||||
|
||||
// respect err.status
|
||||
if (err.status) res.statusCode = err.status;
|
||||
|
||||
// production gets a basic error message
|
||||
var msg = 'production' == env
|
||||
? http.STATUS_CODES[res.statusCode]
|
||||
: err.stack || err.toString();
|
||||
|
||||
// log to stderr in a non-test env
|
||||
if ('test' != env) console.error(err.stack || err.toString());
|
||||
if (res.headerSent) return req.socket.destroy();
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
res.setHeader('Content-Length', Buffer.byteLength(msg));
|
||||
if ('HEAD' == req.method) return res.end();
|
||||
res.end(msg);
|
||||
} else {
|
||||
debug('default 404');
|
||||
res.statusCode = 404;
|
||||
res.setHeader('Content-Type', 'text/plain');
|
||||
if ('HEAD' == req.method) return res.end();
|
||||
res.end('Cannot ' + req.method + ' ' + utils.escape(req.originalUrl));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
path = utils.parseUrl(req).pathname;
|
||||
if (undefined == path) path = '/';
|
||||
|
||||
// skip this layer if the route doesn't match.
|
||||
if (0 != path.toLowerCase().indexOf(layer.route.toLowerCase())) return next(err);
|
||||
|
||||
c = path[layer.route.length];
|
||||
if (c && '/' != c && '.' != c) return next(err);
|
||||
|
||||
// Call the layer handler
|
||||
// Trim off the part of the url that matches the route
|
||||
removed = layer.route;
|
||||
req.url = req.url.substr(removed.length);
|
||||
|
||||
// Ensure leading slash
|
||||
if (!fqdn && '/' != req.url[0]) {
|
||||
req.url = '/' + req.url;
|
||||
slashAdded = true;
|
||||
}
|
||||
|
||||
debug('%s', layer.handle.name || 'anonymous');
|
||||
var arity = layer.handle.length;
|
||||
if (err) {
|
||||
if (arity === 4) {
|
||||
layer.handle(err, req, res, next);
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
} else if (arity < 4) {
|
||||
layer.handle(req, res, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
} catch (e) {
|
||||
next(e);
|
||||
}
|
||||
}
|
||||
next();
|
||||
};
|
||||
|
||||
/**
|
||||
* Listen for connections.
|
||||
*
|
||||
* This method takes the same arguments
|
||||
* as node's `http.Server#listen()`.
|
||||
*
|
||||
* HTTP and HTTPS:
|
||||
*
|
||||
* If you run your application both as HTTP
|
||||
* and HTTPS you may wrap them individually,
|
||||
* since your Connect "server" is really just
|
||||
* a JavaScript `Function`.
|
||||
*
|
||||
* var connect = require('connect')
|
||||
* , http = require('http')
|
||||
* , https = require('https');
|
||||
*
|
||||
* var app = connect();
|
||||
*
|
||||
* http.createServer(app).listen(80);
|
||||
* https.createServer(options, app).listen(443);
|
||||
*
|
||||
* @return {http.Server}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
app.listen = function(){
|
||||
var server = http.createServer(this);
|
||||
return server.listen.apply(server, arguments);
|
||||
};
|
75
nodeartnet/node_modules/express/node_modules/connect/lib/public/directory.html
generated
vendored
Normal file
75
nodeartnet/node_modules/express/node_modules/connect/lib/public/directory.html
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>listing directory {directory}</title>
|
||||
<style>{style}</style>
|
||||
<script>
|
||||
function $(id){
|
||||
var el = 'string' == typeof id
|
||||
? document.getElementById(id)
|
||||
: id;
|
||||
|
||||
el.on = function(event, fn){
|
||||
if ('content loaded' == event) event = 'DOMContentLoaded';
|
||||
el.addEventListener(event, fn, false);
|
||||
};
|
||||
|
||||
el.all = function(selector){
|
||||
return $(el.querySelectorAll(selector));
|
||||
};
|
||||
|
||||
el.each = function(fn){
|
||||
for (var i = 0, len = el.length; i < len; ++i) {
|
||||
fn($(el[i]), i);
|
||||
}
|
||||
};
|
||||
|
||||
el.getClasses = function(){
|
||||
return this.getAttribute('class').split(/\s+/);
|
||||
};
|
||||
|
||||
el.addClass = function(name){
|
||||
var classes = this.getAttribute('class');
|
||||
el.setAttribute('class', classes
|
||||
? classes + ' ' + name
|
||||
: name);
|
||||
};
|
||||
|
||||
el.removeClass = function(name){
|
||||
var classes = this.getClasses().filter(function(curr){
|
||||
return curr != name;
|
||||
});
|
||||
this.setAttribute('class', classes);
|
||||
};
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
function search() {
|
||||
var str = $('search').value
|
||||
, links = $('files').all('a');
|
||||
|
||||
links.each(function(link){
|
||||
var text = link.textContent;
|
||||
|
||||
if ('..' == text) return;
|
||||
if (str.length && ~text.indexOf(str)) {
|
||||
link.addClass('highlight');
|
||||
} else {
|
||||
link.removeClass('highlight');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(window).on('content loaded', function(){
|
||||
$('search').on('keyup', search);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body class="directory">
|
||||
<input id="search" type="text" placeholder="Search" autocomplete="off" />
|
||||
<div id="wrapper">
|
||||
<h1>{linked-path}</h1>
|
||||
{files}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
13
nodeartnet/node_modules/express/node_modules/connect/lib/public/error.html
generated
vendored
Normal file
13
nodeartnet/node_modules/express/node_modules/connect/lib/public/error.html
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>{error}</title>
|
||||
<style>{style}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<h1>{title}</h1>
|
||||
<h2><em>{statusCode}</em> {error}</h2>
|
||||
<ul id="stacktrace">{stack}</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
nodeartnet/node_modules/express/node_modules/connect/lib/public/favicon.ico
generated
vendored
Normal file
BIN
nodeartnet/node_modules/express/node_modules/connect/lib/public/favicon.ico
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
nodeartnet/node_modules/express/node_modules/connect/lib/public/icons/page.png
generated
vendored
Normal file
BIN
nodeartnet/node_modules/express/node_modules/connect/lib/public/icons/page.png
generated
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 635 B |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue