Tie all submit endpoints and image upload endpoints together.
This commit is contained in:
parent
0785506fad
commit
32d3ceeaf3
@ -18,6 +18,8 @@
|
|||||||
<link href="https://fonts.googleapis.com/css2?family=M+PLUS+1p:wght@300;400&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=M+PLUS+1p:wght@300;400&display=swap" rel="stylesheet">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans+Condensed:wght@700&family=Open+Sans:wght@400;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Open+Sans+Condensed:wght@700&family=Open+Sans:wght@400;700&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
|
||||||
|
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
|
||||||
|
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
|
@ -98,3 +98,48 @@ background: linear-gradient(180deg, rgba(251,251,251,1) 0%, rgba(240,255,255,1)
|
|||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.files input {
|
||||||
|
outline: 2px dashed #92b0b3;
|
||||||
|
outline-offset: -10px;
|
||||||
|
-webkit-transition: outline-offset .15s ease-in-out, background-color .15s linear;
|
||||||
|
transition: outline-offset .15s ease-in-out, background-color .15s linear;
|
||||||
|
padding: 120px 0px 85px 35%;
|
||||||
|
text-align: center !important;
|
||||||
|
margin: 0;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
.files input:focus{ outline: 2px dashed #92b0b3; outline-offset: -10px;
|
||||||
|
-webkit-transition: outline-offset .15s ease-in-out, background-color .15s linear;
|
||||||
|
transition: outline-offset .15s ease-in-out, background-color .15s linear; border:1px solid #92b0b3;
|
||||||
|
}
|
||||||
|
.files{ position:relative}
|
||||||
|
.files:after { pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 140px;
|
||||||
|
left: 0;
|
||||||
|
width: 50px;
|
||||||
|
right: 0;
|
||||||
|
height: 56px;
|
||||||
|
content: "";
|
||||||
|
background-image: url(https://image.flaticon.com/icons/png/128/109/109612.png);
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
background-size: 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
.color input{ background-color:#f0f0ff;}
|
||||||
|
.files:before {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 0; pointer-events: none;
|
||||||
|
width: 100%;
|
||||||
|
right: 0;
|
||||||
|
height: 72px;
|
||||||
|
content: " or drag it here. ";
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
color: #000000;
|
||||||
|
text-transform: capitalize;
|
||||||
|
text-align: center;
|
||||||
|
}
|
@ -275,6 +275,35 @@ function Rankings(){
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Submit() {
|
||||||
|
var [file,setFile] = useState(null);
|
||||||
|
|
||||||
|
var prepFile = (e)=>{
|
||||||
|
setFile(e.currentTarget.files[0])
|
||||||
|
}
|
||||||
|
var uploadFile = (e)=>{
|
||||||
|
const data = new FormData()
|
||||||
|
data.append('file', file)
|
||||||
|
/*data.append("username","sigonasr2");
|
||||||
|
data.append("authentication_token","sig");*/
|
||||||
|
axios.post("http://projectdivar.com/upload", data, {})
|
||||||
|
.then(res => {
|
||||||
|
console.log(res.statusText)
|
||||||
|
})
|
||||||
|
.catch((err)=>{console.log(err.message)})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<form method="post" action="#" id="#">
|
||||||
|
<div className="form-group color files">
|
||||||
|
<h3>Submit your play</h3>
|
||||||
|
<i>Plays can be a single image or a bunch of images in a zip file!</i>
|
||||||
|
<hr/>
|
||||||
|
<input type="file" name="file" className="form-control" onChange={(e)=>{prepFile(e)}}/>
|
||||||
|
<button type="button" className="btn btn-primary btn-block" onClick={(e)=>{uploadFile(e)}}>Upload</button>
|
||||||
|
</div>
|
||||||
|
</form>);
|
||||||
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (<Router>
|
return (<Router>
|
||||||
<div className="container content">
|
<div className="container content">
|
||||||
@ -303,6 +332,9 @@ function App() {
|
|||||||
<Route path="/user/:username">
|
<Route path="/user/:username">
|
||||||
<Profile/>
|
<Profile/>
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/submitplay">
|
||||||
|
<Submit/>
|
||||||
|
</Route>
|
||||||
<Route path="/">
|
<Route path="/">
|
||||||
<h1 className="title">Project DivaR</h1>
|
<h1 className="title">Project DivaR</h1>
|
||||||
Under construction!
|
Under construction!
|
||||||
|
@ -8,6 +8,13 @@ module.exports = function(app) {
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
app.use(
|
||||||
|
"/upload",
|
||||||
|
createProxyMiddleware({
|
||||||
|
target: 'http://server:4501',
|
||||||
|
changeOrigin: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
app.use(
|
app.use(
|
||||||
"/song/:songname",
|
"/song/:songname",
|
||||||
createProxyMiddleware({
|
createProxyMiddleware({
|
||||||
@ -113,4 +120,11 @@ module.exports = function(app) {
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
app.use(
|
||||||
|
"/files",
|
||||||
|
createProxyMiddleware({
|
||||||
|
target: 'http://server:4501',
|
||||||
|
changeOrigin: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
};
|
};
|
@ -1,22 +0,0 @@
|
|||||||
# Getting Started
|
|
||||||
|
|
||||||
### Reference Documentation
|
|
||||||
For further reference, please consider the following sections:
|
|
||||||
|
|
||||||
* [Official Gradle documentation](https://docs.gradle.org)
|
|
||||||
* [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/gradle-plugin/reference/html/)
|
|
||||||
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/gradle-plugin/reference/html/#build-image)
|
|
||||||
* [Spring Web](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications)
|
|
||||||
|
|
||||||
### Guides
|
|
||||||
The following guides illustrate how to use some features concretely:
|
|
||||||
|
|
||||||
* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
|
|
||||||
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
|
|
||||||
* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/)
|
|
||||||
|
|
||||||
### Additional Links
|
|
||||||
These additional references should also help you:
|
|
||||||
|
|
||||||
* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'org.springframework.boot' version '2.3.1.RELEASE'
|
|
||||||
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
|
|
||||||
id 'java'
|
|
||||||
}
|
|
||||||
|
|
||||||
group = 'com.example'
|
|
||||||
version = '0.0.1-SNAPSHOT'
|
|
||||||
sourceCompatibility = '1.8'
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
|
||||||
testImplementation('org.springframework.boot:spring-boot-starter-test') {
|
|
||||||
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
server.port=4503
|
|
BIN
imgparser/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
imgparser/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@ -1,5 +0,0 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
|
||||||
distributionPath=wrapper/dists
|
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
|
185
imgparser/gradlew
vendored
185
imgparser/gradlew
vendored
@ -1,185 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright 2015 the original author or authors.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
##
|
|
||||||
## Gradle start up script for UN*X
|
|
||||||
##
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
|
||||||
# Resolve links: $0 may be a link
|
|
||||||
PRG="$0"
|
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
|
||||||
ls=`ls -ld "$PRG"`
|
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
|
||||||
PRG="$link"
|
|
||||||
else
|
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=`basename "$0"`
|
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
||||||
MAX_FD="maximum"
|
|
||||||
|
|
||||||
warn () {
|
|
||||||
echo "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
die () {
|
|
||||||
echo
|
|
||||||
echo "$*"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
|
||||||
cygwin=false
|
|
||||||
msys=false
|
|
||||||
darwin=false
|
|
||||||
nonstop=false
|
|
||||||
case "`uname`" in
|
|
||||||
CYGWIN* )
|
|
||||||
cygwin=true
|
|
||||||
;;
|
|
||||||
Darwin* )
|
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
|
||||||
else
|
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
|
||||||
fi
|
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
JAVACMD="java"
|
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
|
||||||
if [ $? -eq 0 ] ; then
|
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
ulimit -n $MAX_FD
|
|
||||||
if [ $? -ne 0 ] ; then
|
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=`expr $i + 1`
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
0) set -- ;;
|
|
||||||
1) set -- "$args0" ;;
|
|
||||||
2) set -- "$args0" "$args1" ;;
|
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Escape application args
|
|
||||||
save () {
|
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
|
||||||
echo " "
|
|
||||||
}
|
|
||||||
APP_ARGS=`save "$@"`
|
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
|
104
imgparser/gradlew.bat
vendored
104
imgparser/gradlew.bat
vendored
@ -1,104 +0,0 @@
|
|||||||
@rem
|
|
||||||
@rem Copyright 2015 the original author or authors.
|
|
||||||
@rem
|
|
||||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
@rem you may not use this file except in compliance with the License.
|
|
||||||
@rem You may obtain a copy of the License at
|
|
||||||
@rem
|
|
||||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
@rem
|
|
||||||
@rem Unless required by applicable law or agreed to in writing, software
|
|
||||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
@rem See the License for the specific language governing permissions and
|
|
||||||
@rem limitations under the License.
|
|
||||||
@rem
|
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
|
||||||
@rem ##########################################################################
|
|
||||||
@rem
|
|
||||||
@rem Gradle startup script for Windows
|
|
||||||
@rem
|
|
||||||
@rem ##########################################################################
|
|
||||||
|
|
||||||
@rem Set local scope for the variables with windows NT shell
|
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
|
||||||
set APP_BASE_NAME=%~n0
|
|
||||||
set APP_HOME=%DIRNAME%
|
|
||||||
|
|
||||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
|
||||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
|
||||||
|
|
||||||
@rem Find java.exe
|
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
|
||||||
if "%ERRORLEVEL%" == "0" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:findJavaFromJavaHome
|
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:init
|
|
||||||
@rem Get command-line arguments, handling Windows variants
|
|
||||||
|
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
|
||||||
|
|
||||||
:win9xME_args
|
|
||||||
@rem Slurp the command line arguments.
|
|
||||||
set CMD_LINE_ARGS=
|
|
||||||
set _SKIP=2
|
|
||||||
|
|
||||||
:win9xME_args_slurp
|
|
||||||
if "x%~1" == "x" goto execute
|
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
|
||||||
|
|
||||||
:execute
|
|
||||||
@rem Setup the command line
|
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
|
||||||
|
|
||||||
:end
|
|
||||||
@rem End local scope for the variables with windows NT shell
|
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
|
||||||
|
|
||||||
:fail
|
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
||||||
rem the _cmd.exe /c_ return code!
|
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:mainEnd
|
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
|
||||||
|
|
||||||
:omega
|
|
1
imgparser/projectDivaImgParser
Submodule
1
imgparser/projectDivaImgParser
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit c23231e281c8d55f275be235158f326244e1c445
|
@ -1 +0,0 @@
|
|||||||
rootProject.name = 'demo'
|
|
@ -1,19 +0,0 @@
|
|||||||
package com.example.demo;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class Controller {
|
|
||||||
|
|
||||||
@GetMapping("/image")
|
|
||||||
public HashMap<String,String> helloWorld(@RequestParam("url") String url){
|
|
||||||
HashMap<String,String> map = new HashMap<>();
|
|
||||||
map.put("test1",Integer.toString(1));
|
|
||||||
map.put("test2","Hello World");
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
package com.example.demo;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class Controller {
|
|
||||||
|
|
||||||
@GetMapping("/")
|
|
||||||
public String helloWorld() {
|
|
||||||
return "Hello from Spring!";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package com.example.demo;
|
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
public class DemoApplication {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
SpringApplication.run(DemoApplication.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
server.port=4503
|
|
@ -1,13 +0,0 @@
|
|||||||
package com.example.demo;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
class DemoApplicationTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void contextLoads() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
1
server/.gitignore
vendored
1
server/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
.env.twitter
|
.env.twitter
|
||||||
|
files
|
@ -12,6 +12,12 @@ app.use(
|
|||||||
extended: true,
|
extended: true,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
const fileUpload = require('express-fileupload');
|
||||||
|
app.use(
|
||||||
|
fileUpload({createParentPath:true,
|
||||||
|
safeFileNames: true, preserveExtension: true})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let allowCrossDomain = function(req, res, next) {
|
let allowCrossDomain = function(req, res, next) {
|
||||||
@ -77,6 +83,29 @@ app.delete('/remove',(req,res)=>{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.post('/upload', function(req, res) {
|
||||||
|
if (!req.files || Object.keys(req.files).length === 0 || req.body.username===undefined || req.body.authentication_token===undefined) {
|
||||||
|
return res.status(400).send('No files were uploaded. Invalid parameters.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = req.files.file;
|
||||||
|
|
||||||
|
var uploads = 0;
|
||||||
|
var userId = -1;
|
||||||
|
var fileLoc = "";
|
||||||
|
db.query("select uploads,id from users where username=$1",[req.body.username])
|
||||||
|
.then((data)=>{uploads=data.rows[0].uploads;
|
||||||
|
userId=data.rows[0].id;
|
||||||
|
fileLoc = "files/plays/"+userId+"/"+uploads;
|
||||||
|
return file.mv(fileLoc);
|
||||||
|
})
|
||||||
|
.then((data)=>{return db.query("update users set uploads=$1 where username=$2",[Number(uploads)+1,req.body.username])})
|
||||||
|
.then((data)=>{return axios.post("http://projectdivar.com/image",{url:"http://projectdivar.com/"+fileLoc,user:req.body.username,auth:req.body.authentication_token})})
|
||||||
|
.then((data)=>{res.status(200).send(data.data)})
|
||||||
|
.catch((err)=>{res.status(500).send(err.message)})
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
app.post('/submit', (req, res) => {
|
app.post('/submit', (req, res) => {
|
||||||
if (req.body &&
|
if (req.body &&
|
||||||
req.body.username!==undefined && req.body.authentication_token!==undefined && req.body.song!==undefined && req.body.difficulty!==undefined && req.body.cool!==undefined && req.body.fine!==undefined && req.body.safe!==undefined && req.body.sad!==undefined && req.body.worst!==undefined && req.body.percent!==undefined) {
|
req.body.username!==undefined && req.body.authentication_token!==undefined && req.body.song!==undefined && req.body.difficulty!==undefined && req.body.cool!==undefined && req.body.fine!==undefined && req.body.safe!==undefined && req.body.sad!==undefined && req.body.worst!==undefined && req.body.percent!==undefined) {
|
||||||
@ -88,7 +117,18 @@ app.post('/submit', (req, res) => {
|
|||||||
|
|
||||||
if (!(req.body.difficulty==="H"||req.body.difficulty==="N"||req.body.difficulty==="E"||req.body.difficulty==="EX"||req.body.difficulty==="EXEX"))
|
if (!(req.body.difficulty==="H"||req.body.difficulty==="N"||req.body.difficulty==="E"||req.body.difficulty==="EX"||req.body.difficulty==="EXEX"))
|
||||||
{throw new Error("Invalid difficulty!")}
|
{throw new Error("Invalid difficulty!")}
|
||||||
var songsubmitdata={},isFC=false,songRating=-1,userId = -1,songId=-1,playcount=-1,fccount=-1,cool=-1,fine=-1,safe=-1,sad=-1,worst=-1,alreadyPassed=false,eclear=-1,nclear=-1,hclear=-1,exclear=-1,exexclear=-1;
|
var songsubmitdata={},mod="",combo=-1,gameScore=-1,isFC=false,songRating=-1,userId = -1,songId=-1,playcount=-1,fccount=-1,cool=-1,fine=-1,safe=-1,sad=-1,worst=-1,alreadyPassed=false,eclear=-1,nclear=-1,hclear=-1,exclear=-1,exexclear=-1;
|
||||||
|
|
||||||
|
if (req.body.mod!==undefined) {
|
||||||
|
mod = req.body.mod;
|
||||||
|
}
|
||||||
|
if (req.body.combo!==undefined) {
|
||||||
|
combo = req.body.combo;
|
||||||
|
}
|
||||||
|
if (req.body.gameScore!==undefined) {
|
||||||
|
gameScore = req.body.gameScore;
|
||||||
|
}
|
||||||
|
|
||||||
db.query("select id,authentication_token,playcount,fccount,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear from users where username=$1 limit 1",[req.body.username])
|
db.query("select id,authentication_token,playcount,fccount,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear from users where username=$1 limit 1",[req.body.username])
|
||||||
.then((data)=>{if(data && data.rows.length>0){if (data.rows[0].authentication_token===req.body.authentication_token){
|
.then((data)=>{if(data && data.rows.length>0){if (data.rows[0].authentication_token===req.body.authentication_token){
|
||||||
var obj = data.rows[0];
|
var obj = data.rows[0];
|
||||||
@ -98,11 +138,11 @@ app.post('/submit', (req, res) => {
|
|||||||
})
|
})
|
||||||
.then((data)=>{if(data && data.rows.length>0){songId=data.rows[0].id; return db.query('select rating from songdata where songid=$1 and difficulty=$2 limit 1',[songId,req.body.difficulty])}else{throw new Error("Could not find song.")}})
|
.then((data)=>{if(data && data.rows.length>0){songId=data.rows[0].id; return db.query('select rating from songdata where songid=$1 and difficulty=$2 limit 1',[songId,req.body.difficulty])}else{throw new Error("Could not find song.")}})
|
||||||
.then((data)=>{songRating=data.rows[0].rating;return db.query("select id from plays where userid=$1 and score>0 and difficulty=$2 and songid=$3 limit 1",[userId,req.body.difficulty,songId])})
|
.then((data)=>{songRating=data.rows[0].rating;return db.query("select id from plays where userid=$1 and score>0 and difficulty=$2 and songid=$3 limit 1",[userId,req.body.difficulty,songId])})
|
||||||
.then((data)=>{if(data && data.rows.length>0){alreadyPassed=true;/*console.log(data);*/};var score=CalculateSongScore({rating:songRating,cool:req.body.cool,fine:req.body.fine,safe:req.body.safe,sad:req.body.sad,worst:req.body.worst,percent:req.body.percent,difficulty:req.body.difficulty,fail:fail});return db.query("insert into plays(songId,userId,difficulty,cool,fine,safe,sad,worst,percent,date,score,fail) values($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12) returning *",[songId,userId,req.body.difficulty,req.body.cool,req.body.fine,req.body.safe,req.body.sad,req.body.worst,req.body.percent,new Date(),score,fail])})
|
.then((data)=>{if(data && data.rows.length>0){alreadyPassed=true;/*console.log(data);*/};var score=CalculateSongScore({rating:songRating,cool:req.body.cool,fine:req.body.fine,safe:req.body.safe,sad:req.body.sad,worst:req.body.worst,percent:req.body.percent,difficulty:req.body.difficulty,fail:fail});return db.query("insert into plays(songId,userId,difficulty,cool,fine,safe,sad,worst,percent,date,score,fail,mod,combo,gamescore) values($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) returning *",[songId,userId,req.body.difficulty,req.body.cool,req.body.fine,req.body.safe,req.body.sad,req.body.worst,req.body.percent,new Date(),score,fail,mod,combo,gameScore])})
|
||||||
.then((data)=>{if(data && data.rows.length>0){
|
.then((data)=>{if(data && data.rows.length>0){
|
||||||
songsubmitdata = data.rows[0];
|
songsubmitdata = data.rows[0];
|
||||||
//console.log(alreadyPassed+" / "+typeof(alreadyPassed))
|
//console.log(alreadyPassed+" / "+typeof(alreadyPassed))
|
||||||
if(alreadyPassed===false){switch(req.body.difficulty){case"E":{eclear++}break;case"N":{nclear++}break;case"H":{hclear++}break;case"EX":{exclear++}break;case"EXEX":{exexclear++}break;}}
|
if(alreadyPassed===false && songsubmitdata.score>0){switch(req.body.difficulty){case"E":{eclear++}break;case"N":{nclear++}break;case"H":{hclear++}break;case"EX":{exclear++}break;case"EXEX":{exexclear++}break;}}
|
||||||
isFC = songsubmitdata.safe===0 && songsubmitdata.sad===0 && songsubmitdata.worst===0;
|
isFC = songsubmitdata.safe===0 && songsubmitdata.sad===0 && songsubmitdata.worst===0;
|
||||||
return CalculateRating(req.body.username)}else{throw new Error("Could not submit song.")}})
|
return CalculateRating(req.body.username)}else{throw new Error("Could not submit song.")}})
|
||||||
.then((data)=>{return db.query("update users set rating=$1,last_played=$3,playcount=$4,fccount=$5,cool=$6,fine=$7,safe=$8,sad=$9,worst=$10,eclear=$11,nclear=$12,hclear=$13,exclear=$14,exexclear=$15 where username=$2",[data,req.body.username,new Date(),++playcount,fccount+((isFC)?1:0),cool+Number(req.body.cool),fine+Number(req.body.fine),safe+Number(req.body.safe),sad+Number(req.body.sad),worst+Number(req.body.worst),eclear,nclear,hclear,exclear,exexclear])})
|
.then((data)=>{return db.query("update users set rating=$1,last_played=$3,playcount=$4,fccount=$5,cool=$6,fine=$7,safe=$8,sad=$9,worst=$10,eclear=$11,nclear=$12,hclear=$13,exclear=$14,exexclear=$15 where username=$2",[data,req.body.username,new Date(),++playcount,fccount+((isFC)?1:0),cool+Number(req.body.cool),fine+Number(req.body.fine),safe+Number(req.body.safe),sad+Number(req.body.sad),worst+Number(req.body.worst),eclear,nclear,hclear,exclear,exexclear])})
|
||||||
@ -315,6 +355,9 @@ function Process(data){
|
|||||||
}
|
}
|
||||||
return "Done!";
|
return "Done!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.use('/files',express.static('files'))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
axios.get('https://api.twitter.com/1.1/search/tweets.json?q=@divarbot', {
|
axios.get('https://api.twitter.com/1.1/search/tweets.json?q=@divarbot', {
|
||||||
headers: {
|
headers: {
|
||||||
|
16
server/node_modules/busboy/.travis.yml
generated
vendored
Normal file
16
server/node_modules/busboy/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
sudo: false
|
||||||
|
language: cpp
|
||||||
|
notifications:
|
||||||
|
email: false
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- TRAVIS_NODE_VERSION="4"
|
||||||
|
- TRAVIS_NODE_VERSION="6"
|
||||||
|
- TRAVIS_NODE_VERSION="8"
|
||||||
|
- TRAVIS_NODE_VERSION="10"
|
||||||
|
install:
|
||||||
|
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
|
||||||
|
- node --version
|
||||||
|
- npm --version
|
||||||
|
- npm install
|
||||||
|
script: npm test
|
19
server/node_modules/busboy/LICENSE
generated
vendored
Normal file
19
server/node_modules/busboy/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright Brian White. All rights reserved.
|
||||||
|
|
||||||
|
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.
|
222
server/node_modules/busboy/README.md
generated
vendored
Normal file
222
server/node_modules/busboy/README.md
generated
vendored
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
Description
|
||||||
|
===========
|
||||||
|
|
||||||
|
A node.js module for parsing incoming HTML form data.
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
============
|
||||||
|
|
||||||
|
* [node.js](http://nodejs.org/) -- v4.5.0 or newer
|
||||||
|
|
||||||
|
|
||||||
|
Install
|
||||||
|
=======
|
||||||
|
|
||||||
|
npm install busboy
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
========
|
||||||
|
|
||||||
|
* Parsing (multipart) with default options:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var http = require('http'),
|
||||||
|
inspect = require('util').inspect;
|
||||||
|
|
||||||
|
var Busboy = require('busboy');
|
||||||
|
|
||||||
|
http.createServer(function(req, res) {
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
var busboy = new Busboy({ headers: req.headers });
|
||||||
|
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
||||||
|
console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype);
|
||||||
|
file.on('data', function(data) {
|
||||||
|
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
|
||||||
|
});
|
||||||
|
file.on('end', function() {
|
||||||
|
console.log('File [' + fieldname + '] Finished');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
|
||||||
|
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
|
||||||
|
});
|
||||||
|
busboy.on('finish', function() {
|
||||||
|
console.log('Done parsing form!');
|
||||||
|
res.writeHead(303, { Connection: 'close', Location: '/' });
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
req.pipe(busboy);
|
||||||
|
} else if (req.method === 'GET') {
|
||||||
|
res.writeHead(200, { Connection: 'close' });
|
||||||
|
res.end('<html><head></head><body>\
|
||||||
|
<form method="POST" enctype="multipart/form-data">\
|
||||||
|
<input type="text" name="textfield"><br />\
|
||||||
|
<input type="file" name="filefield"><br />\
|
||||||
|
<input type="submit">\
|
||||||
|
</form>\
|
||||||
|
</body></html>');
|
||||||
|
}
|
||||||
|
}).listen(8000, function() {
|
||||||
|
console.log('Listening for requests');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Example output, using http://nodejs.org/images/ryan-speaker.jpg as the file:
|
||||||
|
//
|
||||||
|
// Listening for requests
|
||||||
|
// File [filefield]: filename: ryan-speaker.jpg, encoding: binary
|
||||||
|
// File [filefield] got 11971 bytes
|
||||||
|
// Field [textfield]: value: 'testing! :-)'
|
||||||
|
// File [filefield] Finished
|
||||||
|
// Done parsing form!
|
||||||
|
```
|
||||||
|
|
||||||
|
* Save all incoming files to disk:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var http = require('http'),
|
||||||
|
path = require('path'),
|
||||||
|
os = require('os'),
|
||||||
|
fs = require('fs');
|
||||||
|
|
||||||
|
var Busboy = require('busboy');
|
||||||
|
|
||||||
|
http.createServer(function(req, res) {
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
var busboy = new Busboy({ headers: req.headers });
|
||||||
|
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
||||||
|
var saveTo = path.join(os.tmpDir(), path.basename(fieldname));
|
||||||
|
file.pipe(fs.createWriteStream(saveTo));
|
||||||
|
});
|
||||||
|
busboy.on('finish', function() {
|
||||||
|
res.writeHead(200, { 'Connection': 'close' });
|
||||||
|
res.end("That's all folks!");
|
||||||
|
});
|
||||||
|
return req.pipe(busboy);
|
||||||
|
}
|
||||||
|
res.writeHead(404);
|
||||||
|
res.end();
|
||||||
|
}).listen(8000, function() {
|
||||||
|
console.log('Listening for requests');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
* Parsing (urlencoded) with default options:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var http = require('http'),
|
||||||
|
inspect = require('util').inspect;
|
||||||
|
|
||||||
|
var Busboy = require('busboy');
|
||||||
|
|
||||||
|
http.createServer(function(req, res) {
|
||||||
|
if (req.method === 'POST') {
|
||||||
|
var busboy = new Busboy({ headers: req.headers });
|
||||||
|
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
|
||||||
|
console.log('File [' + fieldname + ']: filename: ' + filename);
|
||||||
|
file.on('data', function(data) {
|
||||||
|
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
|
||||||
|
});
|
||||||
|
file.on('end', function() {
|
||||||
|
console.log('File [' + fieldname + '] Finished');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
|
||||||
|
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
|
||||||
|
});
|
||||||
|
busboy.on('finish', function() {
|
||||||
|
console.log('Done parsing form!');
|
||||||
|
res.writeHead(303, { Connection: 'close', Location: '/' });
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
req.pipe(busboy);
|
||||||
|
} else if (req.method === 'GET') {
|
||||||
|
res.writeHead(200, { Connection: 'close' });
|
||||||
|
res.end('<html><head></head><body>\
|
||||||
|
<form method="POST">\
|
||||||
|
<input type="text" name="textfield"><br />\
|
||||||
|
<select name="selectfield">\
|
||||||
|
<option value="1">1</option>\
|
||||||
|
<option value="10">10</option>\
|
||||||
|
<option value="100">100</option>\
|
||||||
|
<option value="9001">9001</option>\
|
||||||
|
</select><br />\
|
||||||
|
<input type="checkbox" name="checkfield">Node.js rules!<br />\
|
||||||
|
<input type="submit">\
|
||||||
|
</form>\
|
||||||
|
</body></html>');
|
||||||
|
}
|
||||||
|
}).listen(8000, function() {
|
||||||
|
console.log('Listening for requests');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Example output:
|
||||||
|
//
|
||||||
|
// Listening for requests
|
||||||
|
// Field [textfield]: value: 'testing! :-)'
|
||||||
|
// Field [selectfield]: value: '9001'
|
||||||
|
// Field [checkfield]: value: 'on'
|
||||||
|
// Done parsing form!
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
===
|
||||||
|
|
||||||
|
_Busboy_ is a _Writable_ stream
|
||||||
|
|
||||||
|
Busboy (special) events
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* **file**(< _string_ >fieldname, < _ReadableStream_ >stream, < _string_ >filename, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new file form field found. `transferEncoding` contains the 'Content-Transfer-Encoding' value for the file stream. `mimeType` contains the 'Content-Type' value for the file stream.
|
||||||
|
* Note: if you listen for this event, you should always handle the `stream` no matter if you care about the file contents or not (e.g. you can simply just do `stream.resume();` if you want to discard the contents), otherwise the 'finish' event will never fire on the Busboy instance. However, if you don't care about **any** incoming files, you can simply not listen for the 'file' event at all and any/all files will be automatically and safely discarded (these discarded files do still count towards `files` and `parts` limits).
|
||||||
|
* If a configured file size limit was reached, `stream` will both have a boolean property `truncated` (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens.
|
||||||
|
|
||||||
|
* **field**(< _string_ >fieldname, < _string_ >value, < _boolean_ >fieldnameTruncated, < _boolean_ >valueTruncated, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new non-file field found.
|
||||||
|
|
||||||
|
* **partsLimit**() - Emitted when specified `parts` limit has been reached. No more 'file' or 'field' events will be emitted.
|
||||||
|
|
||||||
|
* **filesLimit**() - Emitted when specified `files` limit has been reached. No more 'file' events will be emitted.
|
||||||
|
|
||||||
|
* **fieldsLimit**() - Emitted when specified `fields` limit has been reached. No more 'field' events will be emitted.
|
||||||
|
|
||||||
|
|
||||||
|
Busboy methods
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* **(constructor)**(< _object_ >config) - Creates and returns a new Busboy instance.
|
||||||
|
|
||||||
|
* The constructor takes the following valid `config` settings:
|
||||||
|
|
||||||
|
* **headers** - _object_ - These are the HTTP headers of the incoming request, which are used by individual parsers.
|
||||||
|
|
||||||
|
* **highWaterMark** - _integer_ - highWaterMark to use for this Busboy instance (Default: WritableStream default).
|
||||||
|
|
||||||
|
* **fileHwm** - _integer_ - highWaterMark to use for file streams (Default: ReadableStream default).
|
||||||
|
|
||||||
|
* **defCharset** - _string_ - Default character set to use when one isn't defined (Default: 'utf8').
|
||||||
|
|
||||||
|
* **preservePath** - _boolean_ - If paths in the multipart 'filename' field shall be preserved. (Default: false).
|
||||||
|
|
||||||
|
* **limits** - _object_ - Various limits on incoming data. Valid properties are:
|
||||||
|
|
||||||
|
* **fieldNameSize** - _integer_ - Max field name size (in bytes) (Default: 100 bytes).
|
||||||
|
|
||||||
|
* **fieldSize** - _integer_ - Max field value size (in bytes) (Default: 1MB).
|
||||||
|
|
||||||
|
* **fields** - _integer_ - Max number of non-file fields (Default: Infinity).
|
||||||
|
|
||||||
|
* **fileSize** - _integer_ - For multipart forms, the max file size (in bytes) (Default: Infinity).
|
||||||
|
|
||||||
|
* **files** - _integer_ - For multipart forms, the max number of file fields (Default: Infinity).
|
||||||
|
|
||||||
|
* **parts** - _integer_ - For multipart forms, the max number of parts (fields + files) (Default: Infinity).
|
||||||
|
|
||||||
|
* **headerPairs** - _integer_ - For multipart forms, the max number of header key=>value pairs to parse **Default:** 2000 (same as node's http).
|
||||||
|
|
||||||
|
* The constructor can throw errors:
|
||||||
|
|
||||||
|
* **Unsupported content type: $type** - The `Content-Type` isn't one Busboy can parse.
|
||||||
|
|
||||||
|
* **Missing Content-Type** - The provided headers don't include `Content-Type` at all.
|
73
server/node_modules/busboy/deps/encoding/encoding-indexes.js
generated
vendored
Normal file
73
server/node_modules/busboy/deps/encoding/encoding-indexes.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2391
server/node_modules/busboy/deps/encoding/encoding.js
generated
vendored
Normal file
2391
server/node_modules/busboy/deps/encoding/encoding.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
88
server/node_modules/busboy/lib/main.js
generated
vendored
Normal file
88
server/node_modules/busboy/lib/main.js
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
var fs = require('fs'),
|
||||||
|
WritableStream = require('stream').Writable,
|
||||||
|
inherits = require('util').inherits;
|
||||||
|
|
||||||
|
var parseParams = require('./utils').parseParams;
|
||||||
|
|
||||||
|
function Busboy(opts) {
|
||||||
|
if (!(this instanceof Busboy))
|
||||||
|
return new Busboy(opts);
|
||||||
|
if (opts.highWaterMark !== undefined)
|
||||||
|
WritableStream.call(this, { highWaterMark: opts.highWaterMark });
|
||||||
|
else
|
||||||
|
WritableStream.call(this);
|
||||||
|
|
||||||
|
this._done = false;
|
||||||
|
this._parser = undefined;
|
||||||
|
this._finished = false;
|
||||||
|
|
||||||
|
this.opts = opts;
|
||||||
|
if (opts.headers && typeof opts.headers['content-type'] === 'string')
|
||||||
|
this.parseHeaders(opts.headers);
|
||||||
|
else
|
||||||
|
throw new Error('Missing Content-Type');
|
||||||
|
}
|
||||||
|
inherits(Busboy, WritableStream);
|
||||||
|
|
||||||
|
Busboy.prototype.emit = function(ev) {
|
||||||
|
if (ev === 'finish') {
|
||||||
|
if (!this._done) {
|
||||||
|
this._parser && this._parser.end();
|
||||||
|
return;
|
||||||
|
} else if (this._finished) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._finished = true;
|
||||||
|
}
|
||||||
|
WritableStream.prototype.emit.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
Busboy.prototype.parseHeaders = function(headers) {
|
||||||
|
this._parser = undefined;
|
||||||
|
if (headers['content-type']) {
|
||||||
|
var parsed = parseParams(headers['content-type']),
|
||||||
|
matched, type;
|
||||||
|
for (var i = 0; i < TYPES.length; ++i) {
|
||||||
|
type = TYPES[i];
|
||||||
|
if (typeof type.detect === 'function')
|
||||||
|
matched = type.detect(parsed);
|
||||||
|
else
|
||||||
|
matched = type.detect.test(parsed[0]);
|
||||||
|
if (matched)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (matched) {
|
||||||
|
var cfg = {
|
||||||
|
limits: this.opts.limits,
|
||||||
|
headers: headers,
|
||||||
|
parsedConType: parsed,
|
||||||
|
highWaterMark: undefined,
|
||||||
|
fileHwm: undefined,
|
||||||
|
defCharset: undefined,
|
||||||
|
preservePath: false
|
||||||
|
};
|
||||||
|
if (this.opts.highWaterMark)
|
||||||
|
cfg.highWaterMark = this.opts.highWaterMark;
|
||||||
|
if (this.opts.fileHwm)
|
||||||
|
cfg.fileHwm = this.opts.fileHwm;
|
||||||
|
cfg.defCharset = this.opts.defCharset;
|
||||||
|
cfg.preservePath = this.opts.preservePath;
|
||||||
|
this._parser = type(this, cfg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error('Unsupported content type: ' + headers['content-type']);
|
||||||
|
};
|
||||||
|
|
||||||
|
Busboy.prototype._write = function(chunk, encoding, cb) {
|
||||||
|
if (!this._parser)
|
||||||
|
return cb(new Error('Not ready to parse. Missing Content-Type?'));
|
||||||
|
this._parser.write(chunk, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
var TYPES = [
|
||||||
|
require('./types/multipart'),
|
||||||
|
require('./types/urlencoded'),
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = Busboy;
|
325
server/node_modules/busboy/lib/types/multipart.js
generated
vendored
Normal file
325
server/node_modules/busboy/lib/types/multipart.js
generated
vendored
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
// TODO:
|
||||||
|
// * support 1 nested multipart level
|
||||||
|
// (see second multipart example here:
|
||||||
|
// http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data)
|
||||||
|
// * support limits.fieldNameSize
|
||||||
|
// -- this will require modifications to utils.parseParams
|
||||||
|
|
||||||
|
var ReadableStream = require('stream').Readable,
|
||||||
|
inherits = require('util').inherits;
|
||||||
|
|
||||||
|
var Dicer = require('dicer');
|
||||||
|
|
||||||
|
var parseParams = require('../utils').parseParams,
|
||||||
|
decodeText = require('../utils').decodeText,
|
||||||
|
basename = require('../utils').basename;
|
||||||
|
|
||||||
|
var RE_BOUNDARY = /^boundary$/i,
|
||||||
|
RE_FIELD = /^form-data$/i,
|
||||||
|
RE_CHARSET = /^charset$/i,
|
||||||
|
RE_FILENAME = /^filename$/i,
|
||||||
|
RE_NAME = /^name$/i;
|
||||||
|
|
||||||
|
Multipart.detect = /^multipart\/form-data/i;
|
||||||
|
function Multipart(boy, cfg) {
|
||||||
|
if (!(this instanceof Multipart))
|
||||||
|
return new Multipart(boy, cfg);
|
||||||
|
var i,
|
||||||
|
len,
|
||||||
|
self = this,
|
||||||
|
boundary,
|
||||||
|
limits = cfg.limits,
|
||||||
|
parsedConType = cfg.parsedConType || [],
|
||||||
|
defCharset = cfg.defCharset || 'utf8',
|
||||||
|
preservePath = cfg.preservePath,
|
||||||
|
fileopts = (typeof cfg.fileHwm === 'number'
|
||||||
|
? { highWaterMark: cfg.fileHwm }
|
||||||
|
: {});
|
||||||
|
|
||||||
|
for (i = 0, len = parsedConType.length; i < len; ++i) {
|
||||||
|
if (Array.isArray(parsedConType[i])
|
||||||
|
&& RE_BOUNDARY.test(parsedConType[i][0])) {
|
||||||
|
boundary = parsedConType[i][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFinished() {
|
||||||
|
if (nends === 0 && finished && !boy._done) {
|
||||||
|
finished = false;
|
||||||
|
process.nextTick(function() {
|
||||||
|
boy._done = true;
|
||||||
|
boy.emit('finish');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof boundary !== 'string')
|
||||||
|
throw new Error('Multipart: Boundary not found');
|
||||||
|
|
||||||
|
var fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
|
||||||
|
? limits.fieldSize
|
||||||
|
: 1 * 1024 * 1024),
|
||||||
|
fileSizeLimit = (limits && typeof limits.fileSize === 'number'
|
||||||
|
? limits.fileSize
|
||||||
|
: Infinity),
|
||||||
|
filesLimit = (limits && typeof limits.files === 'number'
|
||||||
|
? limits.files
|
||||||
|
: Infinity),
|
||||||
|
fieldsLimit = (limits && typeof limits.fields === 'number'
|
||||||
|
? limits.fields
|
||||||
|
: Infinity),
|
||||||
|
partsLimit = (limits && typeof limits.parts === 'number'
|
||||||
|
? limits.parts
|
||||||
|
: Infinity);
|
||||||
|
|
||||||
|
var nfiles = 0,
|
||||||
|
nfields = 0,
|
||||||
|
nends = 0,
|
||||||
|
curFile,
|
||||||
|
curField,
|
||||||
|
finished = false;
|
||||||
|
|
||||||
|
this._needDrain = false;
|
||||||
|
this._pause = false;
|
||||||
|
this._cb = undefined;
|
||||||
|
this._nparts = 0;
|
||||||
|
this._boy = boy;
|
||||||
|
|
||||||
|
var parserCfg = {
|
||||||
|
boundary: boundary,
|
||||||
|
maxHeaderPairs: (limits && limits.headerPairs)
|
||||||
|
};
|
||||||
|
if (fileopts.highWaterMark)
|
||||||
|
parserCfg.partHwm = fileopts.highWaterMark;
|
||||||
|
if (cfg.highWaterMark)
|
||||||
|
parserCfg.highWaterMark = cfg.highWaterMark;
|
||||||
|
|
||||||
|
this.parser = new Dicer(parserCfg);
|
||||||
|
this.parser.on('drain', function() {
|
||||||
|
self._needDrain = false;
|
||||||
|
if (self._cb && !self._pause) {
|
||||||
|
var cb = self._cb;
|
||||||
|
self._cb = undefined;
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
}).on('part', function onPart(part) {
|
||||||
|
if (++self._nparts > partsLimit) {
|
||||||
|
self.parser.removeListener('part', onPart);
|
||||||
|
self.parser.on('part', skipPart);
|
||||||
|
boy.hitPartsLimit = true;
|
||||||
|
boy.emit('partsLimit');
|
||||||
|
return skipPart(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hack because streams2 _always_ doesn't emit 'end' until nextTick, so let
|
||||||
|
// us emit 'end' early since we know the part has ended if we are already
|
||||||
|
// seeing the next part
|
||||||
|
if (curField) {
|
||||||
|
var field = curField;
|
||||||
|
field.emit('end');
|
||||||
|
field.removeAllListeners('end');
|
||||||
|
}
|
||||||
|
|
||||||
|
part.on('header', function(header) {
|
||||||
|
var contype,
|
||||||
|
fieldname,
|
||||||
|
parsed,
|
||||||
|
charset,
|
||||||
|
encoding,
|
||||||
|
filename,
|
||||||
|
nsize = 0;
|
||||||
|
|
||||||
|
if (header['content-type']) {
|
||||||
|
parsed = parseParams(header['content-type'][0]);
|
||||||
|
if (parsed[0]) {
|
||||||
|
contype = parsed[0].toLowerCase();
|
||||||
|
for (i = 0, len = parsed.length; i < len; ++i) {
|
||||||
|
if (RE_CHARSET.test(parsed[i][0])) {
|
||||||
|
charset = parsed[i][1].toLowerCase();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contype === undefined)
|
||||||
|
contype = 'text/plain';
|
||||||
|
if (charset === undefined)
|
||||||
|
charset = defCharset;
|
||||||
|
|
||||||
|
if (header['content-disposition']) {
|
||||||
|
parsed = parseParams(header['content-disposition'][0]);
|
||||||
|
if (!RE_FIELD.test(parsed[0]))
|
||||||
|
return skipPart(part);
|
||||||
|
for (i = 0, len = parsed.length; i < len; ++i) {
|
||||||
|
if (RE_NAME.test(parsed[i][0])) {
|
||||||
|
fieldname = decodeText(parsed[i][1], 'binary', 'utf8');
|
||||||
|
} else if (RE_FILENAME.test(parsed[i][0])) {
|
||||||
|
filename = decodeText(parsed[i][1], 'binary', 'utf8');
|
||||||
|
if (!preservePath)
|
||||||
|
filename = basename(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return skipPart(part);
|
||||||
|
|
||||||
|
if (header['content-transfer-encoding'])
|
||||||
|
encoding = header['content-transfer-encoding'][0].toLowerCase();
|
||||||
|
else
|
||||||
|
encoding = '7bit';
|
||||||
|
|
||||||
|
var onData,
|
||||||
|
onEnd;
|
||||||
|
if (contype === 'application/octet-stream' || filename !== undefined) {
|
||||||
|
// file/binary field
|
||||||
|
if (nfiles === filesLimit) {
|
||||||
|
if (!boy.hitFilesLimit) {
|
||||||
|
boy.hitFilesLimit = true;
|
||||||
|
boy.emit('filesLimit');
|
||||||
|
}
|
||||||
|
return skipPart(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
++nfiles;
|
||||||
|
|
||||||
|
if (!boy._events.file) {
|
||||||
|
self.parser._ignore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
++nends;
|
||||||
|
var file = new FileStream(fileopts);
|
||||||
|
curFile = file;
|
||||||
|
file.on('end', function() {
|
||||||
|
--nends;
|
||||||
|
self._pause = false;
|
||||||
|
checkFinished();
|
||||||
|
if (self._cb && !self._needDrain) {
|
||||||
|
var cb = self._cb;
|
||||||
|
self._cb = undefined;
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
file._read = function(n) {
|
||||||
|
if (!self._pause)
|
||||||
|
return;
|
||||||
|
self._pause = false;
|
||||||
|
if (self._cb && !self._needDrain) {
|
||||||
|
var cb = self._cb;
|
||||||
|
self._cb = undefined;
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
boy.emit('file', fieldname, file, filename, encoding, contype);
|
||||||
|
|
||||||
|
onData = function(data) {
|
||||||
|
if ((nsize += data.length) > fileSizeLimit) {
|
||||||
|
var extralen = (fileSizeLimit - (nsize - data.length));
|
||||||
|
if (extralen > 0)
|
||||||
|
file.push(data.slice(0, extralen));
|
||||||
|
file.emit('limit');
|
||||||
|
file.truncated = true;
|
||||||
|
part.removeAllListeners('data');
|
||||||
|
} else if (!file.push(data))
|
||||||
|
self._pause = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
onEnd = function() {
|
||||||
|
curFile = undefined;
|
||||||
|
file.push(null);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// non-file field
|
||||||
|
if (nfields === fieldsLimit) {
|
||||||
|
if (!boy.hitFieldsLimit) {
|
||||||
|
boy.hitFieldsLimit = true;
|
||||||
|
boy.emit('fieldsLimit');
|
||||||
|
}
|
||||||
|
return skipPart(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
++nfields;
|
||||||
|
++nends;
|
||||||
|
var buffer = '',
|
||||||
|
truncated = false;
|
||||||
|
curField = part;
|
||||||
|
|
||||||
|
onData = function(data) {
|
||||||
|
if ((nsize += data.length) > fieldSizeLimit) {
|
||||||
|
var extralen = (fieldSizeLimit - (nsize - data.length));
|
||||||
|
buffer += data.toString('binary', 0, extralen);
|
||||||
|
truncated = true;
|
||||||
|
part.removeAllListeners('data');
|
||||||
|
} else
|
||||||
|
buffer += data.toString('binary');
|
||||||
|
};
|
||||||
|
|
||||||
|
onEnd = function() {
|
||||||
|
curField = undefined;
|
||||||
|
if (buffer.length)
|
||||||
|
buffer = decodeText(buffer, 'binary', charset);
|
||||||
|
boy.emit('field', fieldname, buffer, false, truncated, encoding, contype);
|
||||||
|
--nends;
|
||||||
|
checkFinished();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* As of node@2efe4ab761666 (v0.10.29+/v0.11.14+), busboy had become
|
||||||
|
broken. Streams2/streams3 is a huge black box of confusion, but
|
||||||
|
somehow overriding the sync state seems to fix things again (and still
|
||||||
|
seems to work for previous node versions).
|
||||||
|
*/
|
||||||
|
part._readableState.sync = false;
|
||||||
|
|
||||||
|
part.on('data', onData);
|
||||||
|
part.on('end', onEnd);
|
||||||
|
}).on('error', function(err) {
|
||||||
|
if (curFile)
|
||||||
|
curFile.emit('error', err);
|
||||||
|
});
|
||||||
|
}).on('error', function(err) {
|
||||||
|
boy.emit('error', err);
|
||||||
|
}).on('finish', function() {
|
||||||
|
finished = true;
|
||||||
|
checkFinished();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Multipart.prototype.write = function(chunk, cb) {
|
||||||
|
var r;
|
||||||
|
if ((r = this.parser.write(chunk)) && !this._pause)
|
||||||
|
cb();
|
||||||
|
else {
|
||||||
|
this._needDrain = !r;
|
||||||
|
this._cb = cb;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Multipart.prototype.end = function() {
|
||||||
|
var self = this;
|
||||||
|
if (this._nparts === 0 && !self._boy._done) {
|
||||||
|
process.nextTick(function() {
|
||||||
|
self._boy._done = true;
|
||||||
|
self._boy.emit('finish');
|
||||||
|
});
|
||||||
|
} else if (this.parser.writable)
|
||||||
|
this.parser.end();
|
||||||
|
};
|
||||||
|
|
||||||
|
function skipPart(part) {
|
||||||
|
part.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
function FileStream(opts) {
|
||||||
|
if (!(this instanceof FileStream))
|
||||||
|
return new FileStream(opts);
|
||||||
|
ReadableStream.call(this, opts);
|
||||||
|
|
||||||
|
this.truncated = false;
|
||||||
|
}
|
||||||
|
inherits(FileStream, ReadableStream);
|
||||||
|
|
||||||
|
FileStream.prototype._read = function(n) {};
|
||||||
|
|
||||||
|
module.exports = Multipart;
|
214
server/node_modules/busboy/lib/types/urlencoded.js
generated
vendored
Normal file
214
server/node_modules/busboy/lib/types/urlencoded.js
generated
vendored
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
var Decoder = require('../utils').Decoder,
|
||||||
|
decodeText = require('../utils').decodeText;
|
||||||
|
|
||||||
|
var RE_CHARSET = /^charset$/i;
|
||||||
|
|
||||||
|
UrlEncoded.detect = /^application\/x-www-form-urlencoded/i;
|
||||||
|
function UrlEncoded(boy, cfg) {
|
||||||
|
if (!(this instanceof UrlEncoded))
|
||||||
|
return new UrlEncoded(boy, cfg);
|
||||||
|
var limits = cfg.limits,
|
||||||
|
headers = cfg.headers,
|
||||||
|
parsedConType = cfg.parsedConType;
|
||||||
|
this.boy = boy;
|
||||||
|
|
||||||
|
this.fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
|
||||||
|
? limits.fieldSize
|
||||||
|
: 1 * 1024 * 1024);
|
||||||
|
this.fieldNameSizeLimit = (limits && typeof limits.fieldNameSize === 'number'
|
||||||
|
? limits.fieldNameSize
|
||||||
|
: 100);
|
||||||
|
this.fieldsLimit = (limits && typeof limits.fields === 'number'
|
||||||
|
? limits.fields
|
||||||
|
: Infinity);
|
||||||
|
|
||||||
|
var charset;
|
||||||
|
for (var i = 0, len = parsedConType.length; i < len; ++i) {
|
||||||
|
if (Array.isArray(parsedConType[i])
|
||||||
|
&& RE_CHARSET.test(parsedConType[i][0])) {
|
||||||
|
charset = parsedConType[i][1].toLowerCase();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (charset === undefined)
|
||||||
|
charset = cfg.defCharset || 'utf8';
|
||||||
|
|
||||||
|
this.decoder = new Decoder();
|
||||||
|
this.charset = charset;
|
||||||
|
this._fields = 0;
|
||||||
|
this._state = 'key';
|
||||||
|
this._checkingBytes = true;
|
||||||
|
this._bytesKey = 0;
|
||||||
|
this._bytesVal = 0;
|
||||||
|
this._key = '';
|
||||||
|
this._val = '';
|
||||||
|
this._keyTrunc = false;
|
||||||
|
this._valTrunc = false;
|
||||||
|
this._hitlimit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UrlEncoded.prototype.write = function(data, cb) {
|
||||||
|
if (this._fields === this.fieldsLimit) {
|
||||||
|
if (!this.boy.hitFieldsLimit) {
|
||||||
|
this.boy.hitFieldsLimit = true;
|
||||||
|
this.boy.emit('fieldsLimit');
|
||||||
|
}
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
var idxeq, idxamp, i, p = 0, len = data.length;
|
||||||
|
|
||||||
|
while (p < len) {
|
||||||
|
if (this._state === 'key') {
|
||||||
|
idxeq = idxamp = undefined;
|
||||||
|
for (i = p; i < len; ++i) {
|
||||||
|
if (!this._checkingBytes)
|
||||||
|
++p;
|
||||||
|
if (data[i] === 0x3D/*=*/) {
|
||||||
|
idxeq = i;
|
||||||
|
break;
|
||||||
|
} else if (data[i] === 0x26/*&*/) {
|
||||||
|
idxamp = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this._checkingBytes && this._bytesKey === this.fieldNameSizeLimit) {
|
||||||
|
this._hitLimit = true;
|
||||||
|
break;
|
||||||
|
} else if (this._checkingBytes)
|
||||||
|
++this._bytesKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idxeq !== undefined) {
|
||||||
|
// key with assignment
|
||||||
|
if (idxeq > p)
|
||||||
|
this._key += this.decoder.write(data.toString('binary', p, idxeq));
|
||||||
|
this._state = 'val';
|
||||||
|
|
||||||
|
this._hitLimit = false;
|
||||||
|
this._checkingBytes = true;
|
||||||
|
this._val = '';
|
||||||
|
this._bytesVal = 0;
|
||||||
|
this._valTrunc = false;
|
||||||
|
this.decoder.reset();
|
||||||
|
|
||||||
|
p = idxeq + 1;
|
||||||
|
} else if (idxamp !== undefined) {
|
||||||
|
// key with no assignment
|
||||||
|
++this._fields;
|
||||||
|
var key, keyTrunc = this._keyTrunc;
|
||||||
|
if (idxamp > p)
|
||||||
|
key = (this._key += this.decoder.write(data.toString('binary', p, idxamp)));
|
||||||
|
else
|
||||||
|
key = this._key;
|
||||||
|
|
||||||
|
this._hitLimit = false;
|
||||||
|
this._checkingBytes = true;
|
||||||
|
this._key = '';
|
||||||
|
this._bytesKey = 0;
|
||||||
|
this._keyTrunc = false;
|
||||||
|
this.decoder.reset();
|
||||||
|
|
||||||
|
if (key.length) {
|
||||||
|
this.boy.emit('field', decodeText(key, 'binary', this.charset),
|
||||||
|
'',
|
||||||
|
keyTrunc,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
p = idxamp + 1;
|
||||||
|
if (this._fields === this.fieldsLimit)
|
||||||
|
return cb();
|
||||||
|
} else if (this._hitLimit) {
|
||||||
|
// we may not have hit the actual limit if there are encoded bytes...
|
||||||
|
if (i > p)
|
||||||
|
this._key += this.decoder.write(data.toString('binary', p, i));
|
||||||
|
p = i;
|
||||||
|
if ((this._bytesKey = this._key.length) === this.fieldNameSizeLimit) {
|
||||||
|
// yep, we actually did hit the limit
|
||||||
|
this._checkingBytes = false;
|
||||||
|
this._keyTrunc = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (p < len)
|
||||||
|
this._key += this.decoder.write(data.toString('binary', p));
|
||||||
|
p = len;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
idxamp = undefined;
|
||||||
|
for (i = p; i < len; ++i) {
|
||||||
|
if (!this._checkingBytes)
|
||||||
|
++p;
|
||||||
|
if (data[i] === 0x26/*&*/) {
|
||||||
|
idxamp = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this._checkingBytes && this._bytesVal === this.fieldSizeLimit) {
|
||||||
|
this._hitLimit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (this._checkingBytes)
|
||||||
|
++this._bytesVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idxamp !== undefined) {
|
||||||
|
++this._fields;
|
||||||
|
if (idxamp > p)
|
||||||
|
this._val += this.decoder.write(data.toString('binary', p, idxamp));
|
||||||
|
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||||
|
decodeText(this._val, 'binary', this.charset),
|
||||||
|
this._keyTrunc,
|
||||||
|
this._valTrunc);
|
||||||
|
this._state = 'key';
|
||||||
|
|
||||||
|
this._hitLimit = false;
|
||||||
|
this._checkingBytes = true;
|
||||||
|
this._key = '';
|
||||||
|
this._bytesKey = 0;
|
||||||
|
this._keyTrunc = false;
|
||||||
|
this.decoder.reset();
|
||||||
|
|
||||||
|
p = idxamp + 1;
|
||||||
|
if (this._fields === this.fieldsLimit)
|
||||||
|
return cb();
|
||||||
|
} else if (this._hitLimit) {
|
||||||
|
// we may not have hit the actual limit if there are encoded bytes...
|
||||||
|
if (i > p)
|
||||||
|
this._val += this.decoder.write(data.toString('binary', p, i));
|
||||||
|
p = i;
|
||||||
|
if ((this._val === '' && this.fieldSizeLimit === 0)
|
||||||
|
|| (this._bytesVal = this._val.length) === this.fieldSizeLimit) {
|
||||||
|
// yep, we actually did hit the limit
|
||||||
|
this._checkingBytes = false;
|
||||||
|
this._valTrunc = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (p < len)
|
||||||
|
this._val += this.decoder.write(data.toString('binary', p));
|
||||||
|
p = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cb();
|
||||||
|
};
|
||||||
|
|
||||||
|
UrlEncoded.prototype.end = function() {
|
||||||
|
if (this.boy._done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._state === 'key' && this._key.length > 0) {
|
||||||
|
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||||
|
'',
|
||||||
|
this._keyTrunc,
|
||||||
|
false);
|
||||||
|
} else if (this._state === 'val') {
|
||||||
|
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
|
||||||
|
decodeText(this._val, 'binary', this.charset),
|
||||||
|
this._keyTrunc,
|
||||||
|
this._valTrunc);
|
||||||
|
}
|
||||||
|
this.boy._done = true;
|
||||||
|
this.boy.emit('finish');
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = UrlEncoded;
|
172
server/node_modules/busboy/lib/utils.js
generated
vendored
Normal file
172
server/node_modules/busboy/lib/utils.js
generated
vendored
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
var jsencoding = require('../deps/encoding/encoding');
|
||||||
|
|
||||||
|
var RE_ENCODED = /%([a-fA-F0-9]{2})/g;
|
||||||
|
function encodedReplacer(match, byte) {
|
||||||
|
return String.fromCharCode(parseInt(byte, 16));
|
||||||
|
}
|
||||||
|
function parseParams(str) {
|
||||||
|
var res = [],
|
||||||
|
state = 'key',
|
||||||
|
charset = '',
|
||||||
|
inquote = false,
|
||||||
|
escaping = false,
|
||||||
|
p = 0,
|
||||||
|
tmp = '';
|
||||||
|
|
||||||
|
for (var i = 0, len = str.length; i < len; ++i) {
|
||||||
|
if (str[i] === '\\' && inquote) {
|
||||||
|
if (escaping)
|
||||||
|
escaping = false;
|
||||||
|
else {
|
||||||
|
escaping = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (str[i] === '"') {
|
||||||
|
if (!escaping) {
|
||||||
|
if (inquote) {
|
||||||
|
inquote = false;
|
||||||
|
state = 'key';
|
||||||
|
} else
|
||||||
|
inquote = true;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
escaping = false;
|
||||||
|
} else {
|
||||||
|
if (escaping && inquote)
|
||||||
|
tmp += '\\';
|
||||||
|
escaping = false;
|
||||||
|
if ((state === 'charset' || state === 'lang') && str[i] === "'") {
|
||||||
|
if (state === 'charset') {
|
||||||
|
state = 'lang';
|
||||||
|
charset = tmp.substring(1);
|
||||||
|
} else
|
||||||
|
state = 'value';
|
||||||
|
tmp = '';
|
||||||
|
continue;
|
||||||
|
} else if (state === 'key'
|
||||||
|
&& (str[i] === '*' || str[i] === '=')
|
||||||
|
&& res.length) {
|
||||||
|
if (str[i] === '*')
|
||||||
|
state = 'charset';
|
||||||
|
else
|
||||||
|
state = 'value';
|
||||||
|
res[p] = [tmp, undefined];
|
||||||
|
tmp = '';
|
||||||
|
continue;
|
||||||
|
} else if (!inquote && str[i] === ';') {
|
||||||
|
state = 'key';
|
||||||
|
if (charset) {
|
||||||
|
if (tmp.length) {
|
||||||
|
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
|
||||||
|
'binary',
|
||||||
|
charset);
|
||||||
|
}
|
||||||
|
charset = '';
|
||||||
|
}
|
||||||
|
if (res[p] === undefined)
|
||||||
|
res[p] = tmp;
|
||||||
|
else
|
||||||
|
res[p][1] = tmp;
|
||||||
|
tmp = '';
|
||||||
|
++p;
|
||||||
|
continue;
|
||||||
|
} else if (!inquote && (str[i] === ' ' || str[i] === '\t'))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tmp += str[i];
|
||||||
|
}
|
||||||
|
if (charset && tmp.length) {
|
||||||
|
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
|
||||||
|
'binary',
|
||||||
|
charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res[p] === undefined) {
|
||||||
|
if (tmp)
|
||||||
|
res[p] = tmp;
|
||||||
|
} else
|
||||||
|
res[p][1] = tmp;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
exports.parseParams = parseParams;
|
||||||
|
|
||||||
|
|
||||||
|
function decodeText(text, textEncoding, destEncoding) {
|
||||||
|
var ret;
|
||||||
|
if (text && jsencoding.encodingExists(destEncoding)) {
|
||||||
|
try {
|
||||||
|
ret = jsencoding.TextDecoder(destEncoding)
|
||||||
|
.decode(Buffer.from(text, textEncoding));
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
return (typeof ret === 'string' ? ret : text);
|
||||||
|
}
|
||||||
|
exports.decodeText = decodeText;
|
||||||
|
|
||||||
|
|
||||||
|
var HEX = [
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
], RE_PLUS = /\+/g;
|
||||||
|
function Decoder() {
|
||||||
|
this.buffer = undefined;
|
||||||
|
}
|
||||||
|
Decoder.prototype.write = function(str) {
|
||||||
|
// Replace '+' with ' ' before decoding
|
||||||
|
str = str.replace(RE_PLUS, ' ');
|
||||||
|
var res = '';
|
||||||
|
var i = 0, p = 0, len = str.length;
|
||||||
|
for (; i < len; ++i) {
|
||||||
|
if (this.buffer !== undefined) {
|
||||||
|
if (!HEX[str.charCodeAt(i)]) {
|
||||||
|
res += '%' + this.buffer;
|
||||||
|
this.buffer = undefined;
|
||||||
|
--i; // retry character
|
||||||
|
} else {
|
||||||
|
this.buffer += str[i];
|
||||||
|
++p;
|
||||||
|
if (this.buffer.length === 2) {
|
||||||
|
res += String.fromCharCode(parseInt(this.buffer, 16));
|
||||||
|
this.buffer = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (str[i] === '%') {
|
||||||
|
if (i > p) {
|
||||||
|
res += str.substring(p, i);
|
||||||
|
p = i;
|
||||||
|
}
|
||||||
|
this.buffer = '';
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p < len && this.buffer === undefined)
|
||||||
|
res += str.substring(p);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
Decoder.prototype.reset = function() {
|
||||||
|
this.buffer = undefined;
|
||||||
|
};
|
||||||
|
exports.Decoder = Decoder;
|
||||||
|
|
||||||
|
|
||||||
|
function basename(path) {
|
||||||
|
if (typeof path !== 'string')
|
||||||
|
return '';
|
||||||
|
for (var i = path.length - 1; i >= 0; --i) {
|
||||||
|
switch (path.charCodeAt(i)) {
|
||||||
|
case 0x2F: // '/'
|
||||||
|
case 0x5C: // '\'
|
||||||
|
path = path.slice(i + 1);
|
||||||
|
return (path === '..' || path === '.' ? '' : path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (path === '..' || path === '.' ? '' : path);
|
||||||
|
}
|
||||||
|
exports.basename = basename;
|
64
server/node_modules/busboy/package.json
generated
vendored
Normal file
64
server/node_modules/busboy/package.json
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"_from": "busboy@^0.3.1",
|
||||||
|
"_id": "busboy@0.3.1",
|
||||||
|
"_inBundle": false,
|
||||||
|
"_integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==",
|
||||||
|
"_location": "/busboy",
|
||||||
|
"_phantomChildren": {},
|
||||||
|
"_requested": {
|
||||||
|
"type": "range",
|
||||||
|
"registry": true,
|
||||||
|
"raw": "busboy@^0.3.1",
|
||||||
|
"name": "busboy",
|
||||||
|
"escapedName": "busboy",
|
||||||
|
"rawSpec": "^0.3.1",
|
||||||
|
"saveSpec": null,
|
||||||
|
"fetchSpec": "^0.3.1"
|
||||||
|
},
|
||||||
|
"_requiredBy": [
|
||||||
|
"/express-fileupload"
|
||||||
|
],
|
||||||
|
"_resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz",
|
||||||
|
"_shasum": "170899274c5bf38aae27d5c62b71268cd585fd1b",
|
||||||
|
"_spec": "busboy@^0.3.1",
|
||||||
|
"_where": "/home/sigonasr2/divar/server/node_modules/express-fileupload",
|
||||||
|
"author": {
|
||||||
|
"name": "Brian White",
|
||||||
|
"email": "mscdex@mscdex.net"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/mscdex/busboy/issues"
|
||||||
|
},
|
||||||
|
"bundleDependencies": false,
|
||||||
|
"dependencies": {
|
||||||
|
"dicer": "0.3.0"
|
||||||
|
},
|
||||||
|
"deprecated": false,
|
||||||
|
"description": "A streaming parser for HTML form data for node.js",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.5.0"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/mscdex/busboy#readme",
|
||||||
|
"keywords": [
|
||||||
|
"uploads",
|
||||||
|
"forms",
|
||||||
|
"multipart",
|
||||||
|
"form-data"
|
||||||
|
],
|
||||||
|
"licenses": [
|
||||||
|
{
|
||||||
|
"type": "MIT",
|
||||||
|
"url": "http://github.com/mscdex/busboy/raw/master/LICENSE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"main": "./lib/main",
|
||||||
|
"name": "busboy",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+ssh://git@github.com/mscdex/busboy.git"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "node test/test.js"
|
||||||
|
},
|
||||||
|
"version": "0.3.1"
|
||||||
|
}
|
80
server/node_modules/busboy/test/test-types-multipart-stream-pause.js
generated
vendored
Normal file
80
server/node_modules/busboy/test/test-types-multipart-stream-pause.js
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
var Busboy = require('..');
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
var inspect = require('util').inspect;
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
function formDataSection(key, value) {
|
||||||
|
return Buffer.from('\r\n--' + BOUNDARY
|
||||||
|
+ '\r\nContent-Disposition: form-data; name="'
|
||||||
|
+ key + '"\r\n\r\n' + value);
|
||||||
|
}
|
||||||
|
function formDataFile(key, filename, contentType) {
|
||||||
|
return Buffer.concat([
|
||||||
|
Buffer.from('\r\n--' + BOUNDARY + '\r\n'),
|
||||||
|
Buffer.from('Content-Disposition: form-data; name="'
|
||||||
|
+ key + '"; filename="' + filename + '"\r\n'),
|
||||||
|
Buffer.from('Content-Type: ' + contentType + '\r\n\r\n'),
|
||||||
|
Buffer.allocUnsafe(100000)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var BOUNDARY = 'u2KxIV5yF1y+xUspOQCCZopaVgeV6Jxihv35XQJmuTx8X3sh';
|
||||||
|
var reqChunks = [
|
||||||
|
Buffer.concat([
|
||||||
|
formDataFile('file', 'file.bin', 'application/octet-stream'),
|
||||||
|
formDataSection('foo', 'foo value')
|
||||||
|
]),
|
||||||
|
formDataSection('bar', 'bar value'),
|
||||||
|
Buffer.from('\r\n--' + BOUNDARY + '--\r\n')
|
||||||
|
];
|
||||||
|
var busboy = new Busboy({
|
||||||
|
headers: {
|
||||||
|
'content-type': 'multipart/form-data; boundary=' + BOUNDARY
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var finishes = 0;
|
||||||
|
var results = [];
|
||||||
|
var expected = [
|
||||||
|
['file', 'file', 'file.bin', '7bit', 'application/octet-stream'],
|
||||||
|
['field', 'foo', 'foo value', false, false, '7bit', 'text/plain'],
|
||||||
|
['field', 'bar', 'bar value', false, false, '7bit', 'text/plain'],
|
||||||
|
];
|
||||||
|
|
||||||
|
busboy.on('field', function(key, val, keyTrunc, valTrunc, encoding, contype) {
|
||||||
|
results.push(['field', key, val, keyTrunc, valTrunc, encoding, contype]);
|
||||||
|
});
|
||||||
|
busboy.on('file', function(fieldname, stream, filename, encoding, mimeType) {
|
||||||
|
results.push(['file', fieldname, filename, encoding, mimeType]);
|
||||||
|
// Simulate a pipe where the destination is pausing (perhaps due to waiting
|
||||||
|
// for file system write to finish)
|
||||||
|
setTimeout(function() {
|
||||||
|
stream.resume();
|
||||||
|
}, 10);
|
||||||
|
});
|
||||||
|
busboy.on('finish', function() {
|
||||||
|
assert(finishes++ === 0, 'finish emitted multiple times');
|
||||||
|
assert.deepEqual(results.length,
|
||||||
|
expected.length,
|
||||||
|
'Parsed result count mismatch. Saw '
|
||||||
|
+ results.length
|
||||||
|
+ '. Expected: ' + expected.length);
|
||||||
|
|
||||||
|
results.forEach(function(result, i) {
|
||||||
|
assert.deepEqual(result,
|
||||||
|
expected[i],
|
||||||
|
'Result mismatch:\nParsed: ' + inspect(result)
|
||||||
|
+ '\nExpected: ' + inspect(expected[i]));
|
||||||
|
});
|
||||||
|
}).on('error', function(err) {
|
||||||
|
assert(false, 'Unexpected error: ' + err.stack);
|
||||||
|
});
|
||||||
|
|
||||||
|
reqChunks.forEach(function(buf) {
|
||||||
|
busboy.write(buf);
|
||||||
|
});
|
||||||
|
busboy.end();
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert(finishes === 1, 'busboy did not finish');
|
||||||
|
});
|
343
server/node_modules/busboy/test/test-types-multipart.js
generated
vendored
Normal file
343
server/node_modules/busboy/test/test-types-multipart.js
generated
vendored
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
var Busboy = require('..');
|
||||||
|
|
||||||
|
var path = require('path'),
|
||||||
|
inspect = require('util').inspect,
|
||||||
|
assert = require('assert');
|
||||||
|
|
||||||
|
var EMPTY_FN = function() {};
|
||||||
|
|
||||||
|
var t = 0,
|
||||||
|
group = path.basename(__filename, '.js') + '/';
|
||||||
|
var tests = [
|
||||||
|
{ source: [
|
||||||
|
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="file_name_0"',
|
||||||
|
'',
|
||||||
|
'super alpha file',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="file_name_1"',
|
||||||
|
'',
|
||||||
|
'super beta file',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_1"; filename="1k_b.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
expected: [
|
||||||
|
['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain'],
|
||||||
|
['field', 'file_name_1', 'super beta file', false, false, '7bit', 'text/plain'],
|
||||||
|
['file', 'upload_file_0', 1023, 0, '1k_a.dat', '7bit', 'application/octet-stream'],
|
||||||
|
['file', 'upload_file_1', 1023, 0, '1k_b.dat', '7bit', 'application/octet-stream']
|
||||||
|
],
|
||||||
|
what: 'Fields and files'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
'Content-Disposition: form-data; name="cont"',
|
||||||
|
'',
|
||||||
|
'some random content',
|
||||||
|
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
'Content-Disposition: form-data; name="pass"',
|
||||||
|
'',
|
||||||
|
'some random pass',
|
||||||
|
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
'Content-Disposition: form-data; name="bit"',
|
||||||
|
'',
|
||||||
|
'2',
|
||||||
|
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY--'
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
expected: [
|
||||||
|
['field', 'cont', 'some random content', false, false, '7bit', 'text/plain'],
|
||||||
|
['field', 'pass', 'some random pass', false, false, '7bit', 'text/plain'],
|
||||||
|
['field', 'bit', '2', false, false, '7bit', 'text/plain']
|
||||||
|
],
|
||||||
|
what: 'Fields only'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
''
|
||||||
|
],
|
||||||
|
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
expected: [],
|
||||||
|
what: 'No fields and no files'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="file_name_0"',
|
||||||
|
'',
|
||||||
|
'super alpha file',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
limits: {
|
||||||
|
fileSize: 13,
|
||||||
|
fieldSize: 5
|
||||||
|
},
|
||||||
|
expected: [
|
||||||
|
['field', 'file_name_0', 'super', false, true, '7bit', 'text/plain'],
|
||||||
|
['file', 'upload_file_0', 13, 2, '1k_a.dat', '7bit', 'application/octet-stream']
|
||||||
|
],
|
||||||
|
what: 'Fields and files (limits)'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="file_name_0"',
|
||||||
|
'',
|
||||||
|
'super alpha file',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
limits: {
|
||||||
|
files: 0
|
||||||
|
},
|
||||||
|
expected: [
|
||||||
|
['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain']
|
||||||
|
],
|
||||||
|
what: 'Fields and files (limits: 0 files)'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="file_name_0"',
|
||||||
|
'',
|
||||||
|
'super alpha file',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="file_name_1"',
|
||||||
|
'',
|
||||||
|
'super beta file',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_1"; filename="1k_b.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
expected: [
|
||||||
|
['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain'],
|
||||||
|
['field', 'file_name_1', 'super beta file', false, false, '7bit', 'text/plain'],
|
||||||
|
],
|
||||||
|
events: ['field'],
|
||||||
|
what: 'Fields and (ignored) files'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_0"; filename="/tmp/1k_a.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_1"; filename="C:\\files\\1k_b.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_2"; filename="relative/1k_c.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
expected: [
|
||||||
|
['file', 'upload_file_0', 26, 0, '1k_a.dat', '7bit', 'application/octet-stream'],
|
||||||
|
['file', 'upload_file_1', 26, 0, '1k_b.dat', '7bit', 'application/octet-stream'],
|
||||||
|
['file', 'upload_file_2', 26, 0, '1k_c.dat', '7bit', 'application/octet-stream']
|
||||||
|
],
|
||||||
|
what: 'Files with filenames containing paths'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_0"; filename="/absolute/1k_a.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_1"; filename="C:\\absolute\\1k_b.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
'Content-Disposition: form-data; name="upload_file_2"; filename="relative/1k_c.dat"',
|
||||||
|
'Content-Type: application/octet-stream',
|
||||||
|
'',
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
|
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
|
||||||
|
preservePath: true,
|
||||||
|
expected: [
|
||||||
|
['file', 'upload_file_0', 26, 0, '/absolute/1k_a.dat', '7bit', 'application/octet-stream'],
|
||||||
|
['file', 'upload_file_1', 26, 0, 'C:\\absolute\\1k_b.dat', '7bit', 'application/octet-stream'],
|
||||||
|
['file', 'upload_file_2', 26, 0, 'relative/1k_c.dat', '7bit', 'application/octet-stream']
|
||||||
|
],
|
||||||
|
what: 'Paths to be preserved through the preservePath option'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
'Content-Disposition: form-data; name="cont"',
|
||||||
|
'Content-Type: ',
|
||||||
|
'',
|
||||||
|
'some random content',
|
||||||
|
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
'Content-Disposition: ',
|
||||||
|
'',
|
||||||
|
'some random pass',
|
||||||
|
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY--'
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
expected: [
|
||||||
|
['field', 'cont', 'some random content', false, false, '7bit', 'text/plain']
|
||||||
|
],
|
||||||
|
what: 'Empty content-type and empty content-disposition'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['--asdasdasdasd\r\n',
|
||||||
|
'Content-Type: text/plain\r\n',
|
||||||
|
'Content-Disposition: form-data; name="foo"\r\n',
|
||||||
|
'\r\n',
|
||||||
|
'asd\r\n',
|
||||||
|
'--asdasdasdasd--'
|
||||||
|
].join(':)')
|
||||||
|
],
|
||||||
|
boundary: 'asdasdasdasd',
|
||||||
|
expected: [],
|
||||||
|
shouldError: 'Unexpected end of multipart data',
|
||||||
|
what: 'Stopped mid-header'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
'Content-Disposition: form-data; name="cont"',
|
||||||
|
'Content-Type: application/json',
|
||||||
|
'',
|
||||||
|
'{}',
|
||||||
|
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY--',
|
||||||
|
].join('\r\n')
|
||||||
|
],
|
||||||
|
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
expected: [
|
||||||
|
['field', 'cont', '{}', false, false, '7bit', 'application/json']
|
||||||
|
],
|
||||||
|
what: 'content-type for fields'
|
||||||
|
},
|
||||||
|
{ source: [
|
||||||
|
'------WebKitFormBoundaryTB2MiQ36fnSJlrhY--\r\n'
|
||||||
|
],
|
||||||
|
boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
|
||||||
|
expected: [],
|
||||||
|
what: 'empty form'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (t === tests.length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var v = tests[t];
|
||||||
|
|
||||||
|
var busboy = new Busboy({
|
||||||
|
limits: v.limits,
|
||||||
|
preservePath: v.preservePath,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'multipart/form-data; boundary=' + v.boundary
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
finishes = 0,
|
||||||
|
results = [];
|
||||||
|
|
||||||
|
if (v.events === undefined || v.events.indexOf('field') > -1) {
|
||||||
|
busboy.on('field', function(key, val, keyTrunc, valTrunc, encoding, contype) {
|
||||||
|
results.push(['field', key, val, keyTrunc, valTrunc, encoding, contype]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (v.events === undefined || v.events.indexOf('file') > -1) {
|
||||||
|
busboy.on('file', function(fieldname, stream, filename, encoding, mimeType) {
|
||||||
|
var nb = 0,
|
||||||
|
info = ['file',
|
||||||
|
fieldname,
|
||||||
|
nb,
|
||||||
|
0,
|
||||||
|
filename,
|
||||||
|
encoding,
|
||||||
|
mimeType];
|
||||||
|
results.push(info);
|
||||||
|
stream.on('data', function(d) {
|
||||||
|
nb += d.length;
|
||||||
|
}).on('limit', function() {
|
||||||
|
++info[3];
|
||||||
|
}).on('end', function() {
|
||||||
|
info[2] = nb;
|
||||||
|
if (stream.truncated)
|
||||||
|
++info[3];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
busboy.on('finish', function() {
|
||||||
|
assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
|
||||||
|
assert.deepEqual(results.length,
|
||||||
|
v.expected.length,
|
||||||
|
makeMsg(v.what, 'Parsed result count mismatch. Saw '
|
||||||
|
+ results.length
|
||||||
|
+ '. Expected: ' + v.expected.length));
|
||||||
|
|
||||||
|
results.forEach(function(result, i) {
|
||||||
|
assert.deepEqual(result,
|
||||||
|
v.expected[i],
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Result mismatch:\nParsed: ' + inspect(result)
|
||||||
|
+ '\nExpected: ' + inspect(v.expected[i]))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
++t;
|
||||||
|
next();
|
||||||
|
}).on('error', function(err) {
|
||||||
|
if (!v.shouldError || v.shouldError !== err.message)
|
||||||
|
assert(false, makeMsg(v.what, 'Unexpected error: ' + err));
|
||||||
|
});
|
||||||
|
|
||||||
|
v.source.forEach(function(s) {
|
||||||
|
busboy.write(Buffer.from(s, 'utf8'), EMPTY_FN);
|
||||||
|
});
|
||||||
|
busboy.end();
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
|
||||||
|
function makeMsg(what, msg) {
|
||||||
|
return '[' + group + what + ']: ' + msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert(t === tests.length,
|
||||||
|
makeMsg('_exit',
|
||||||
|
'Only finished ' + t + '/' + tests.length + ' tests'));
|
||||||
|
});
|
183
server/node_modules/busboy/test/test-types-urlencoded.js
generated
vendored
Normal file
183
server/node_modules/busboy/test/test-types-urlencoded.js
generated
vendored
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
var Busboy = require('..');
|
||||||
|
|
||||||
|
var path = require('path'),
|
||||||
|
inspect = require('util').inspect,
|
||||||
|
assert = require('assert');
|
||||||
|
|
||||||
|
var EMPTY_FN = function() {};
|
||||||
|
|
||||||
|
var t = 0,
|
||||||
|
group = path.basename(__filename, '.js') + '/';
|
||||||
|
|
||||||
|
var tests = [
|
||||||
|
{ source: ['foo'],
|
||||||
|
expected: [['foo', '', false, false]],
|
||||||
|
what: 'Unassigned value'
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar'],
|
||||||
|
expected: [['foo', 'bar', false, false]],
|
||||||
|
what: 'Assigned value'
|
||||||
|
},
|
||||||
|
{ source: ['foo&bar=baz'],
|
||||||
|
expected: [['foo', '', false, false],
|
||||||
|
['bar', 'baz', false, false]],
|
||||||
|
what: 'Unassigned and assigned value'
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz'],
|
||||||
|
expected: [['foo', 'bar', false, false],
|
||||||
|
['baz', '', false, false]],
|
||||||
|
what: 'Assigned and unassigned value'
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [['foo', 'bar', false, false],
|
||||||
|
['baz', 'bla', false, false]],
|
||||||
|
what: 'Two assigned values'
|
||||||
|
},
|
||||||
|
{ source: ['foo&bar'],
|
||||||
|
expected: [['foo', '', false, false],
|
||||||
|
['bar', '', false, false]],
|
||||||
|
what: 'Two unassigned values'
|
||||||
|
},
|
||||||
|
{ source: ['foo&bar&'],
|
||||||
|
expected: [['foo', '', false, false],
|
||||||
|
['bar', '', false, false]],
|
||||||
|
what: 'Two unassigned values and ampersand'
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar+baz%2Bquux'],
|
||||||
|
expected: [['foo', 'bar baz+quux', false, false]],
|
||||||
|
what: 'Assigned value with (plus) space'
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar%20baz%21'],
|
||||||
|
expected: [['foo', 'bar baz!', false, false]],
|
||||||
|
what: 'Assigned value with encoded bytes'
|
||||||
|
},
|
||||||
|
{ source: ['foo%20bar=baz%20bla%21'],
|
||||||
|
expected: [['foo bar', 'baz bla!', false, false]],
|
||||||
|
what: 'Assigned value with encoded bytes #2'
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar%20baz%21&num=1000'],
|
||||||
|
expected: [['foo', 'bar baz!', false, false],
|
||||||
|
['num', '1000', false, false]],
|
||||||
|
what: 'Two assigned values, one with encoded bytes'
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [],
|
||||||
|
what: 'Limits: zero fields',
|
||||||
|
limits: { fields: 0 }
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [['foo', 'bar', false, false]],
|
||||||
|
what: 'Limits: one field',
|
||||||
|
limits: { fields: 1 }
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [['foo', 'bar', false, false],
|
||||||
|
['baz', 'bla', false, false]],
|
||||||
|
what: 'Limits: field part lengths match limits',
|
||||||
|
limits: { fieldNameSize: 3, fieldSize: 3 }
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [['fo', 'bar', true, false],
|
||||||
|
['ba', 'bla', true, false]],
|
||||||
|
what: 'Limits: truncated field name',
|
||||||
|
limits: { fieldNameSize: 2 }
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [['foo', 'ba', false, true],
|
||||||
|
['baz', 'bl', false, true]],
|
||||||
|
what: 'Limits: truncated field value',
|
||||||
|
limits: { fieldSize: 2 }
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [['fo', 'ba', true, true],
|
||||||
|
['ba', 'bl', true, true]],
|
||||||
|
what: 'Limits: truncated field name and value',
|
||||||
|
limits: { fieldNameSize: 2, fieldSize: 2 }
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [['fo', '', true, true],
|
||||||
|
['ba', '', true, true]],
|
||||||
|
what: 'Limits: truncated field name and zero value limit',
|
||||||
|
limits: { fieldNameSize: 2, fieldSize: 0 }
|
||||||
|
},
|
||||||
|
{ source: ['foo=bar&baz=bla'],
|
||||||
|
expected: [['', '', true, true],
|
||||||
|
['', '', true, true]],
|
||||||
|
what: 'Limits: truncated zero field name and zero value limit',
|
||||||
|
limits: { fieldNameSize: 0, fieldSize: 0 }
|
||||||
|
},
|
||||||
|
{ source: ['&'],
|
||||||
|
expected: [],
|
||||||
|
what: 'Ampersand'
|
||||||
|
},
|
||||||
|
{ source: ['&&&&&'],
|
||||||
|
expected: [],
|
||||||
|
what: 'Many ampersands'
|
||||||
|
},
|
||||||
|
{ source: ['='],
|
||||||
|
expected: [['', '', false, false]],
|
||||||
|
what: 'Assigned value, empty name and value'
|
||||||
|
},
|
||||||
|
{ source: [''],
|
||||||
|
expected: [],
|
||||||
|
what: 'Nothing'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (t === tests.length)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var v = tests[t];
|
||||||
|
|
||||||
|
var busboy = new Busboy({
|
||||||
|
limits: v.limits,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/x-www-form-urlencoded; charset=utf-8'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
finishes = 0,
|
||||||
|
results = [];
|
||||||
|
|
||||||
|
busboy.on('field', function(key, val, keyTrunc, valTrunc) {
|
||||||
|
results.push([key, val, keyTrunc, valTrunc]);
|
||||||
|
});
|
||||||
|
busboy.on('file', function() {
|
||||||
|
throw new Error(makeMsg(v.what, 'Unexpected file'));
|
||||||
|
});
|
||||||
|
busboy.on('finish', function() {
|
||||||
|
assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
|
||||||
|
assert.deepEqual(results.length,
|
||||||
|
v.expected.length,
|
||||||
|
makeMsg(v.what, 'Parsed result count mismatch. Saw '
|
||||||
|
+ results.length
|
||||||
|
+ '. Expected: ' + v.expected.length));
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
results.forEach(function(result) {
|
||||||
|
assert.deepEqual(result,
|
||||||
|
v.expected[i],
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Result mismatch:\nParsed: ' + inspect(result)
|
||||||
|
+ '\nExpected: ' + inspect(v.expected[i]))
|
||||||
|
);
|
||||||
|
++i;
|
||||||
|
});
|
||||||
|
++t;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
v.source.forEach(function(s) {
|
||||||
|
busboy.write(Buffer.from(s, 'utf8'), EMPTY_FN);
|
||||||
|
});
|
||||||
|
busboy.end();
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
|
||||||
|
function makeMsg(what, msg) {
|
||||||
|
return '[' + group + what + ']: ' + msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert(t === tests.length, makeMsg('_exit', 'Only finished ' + t + '/' + tests.length + ' tests'));
|
||||||
|
});
|
66
server/node_modules/busboy/test/test-utils-decoder.js
generated
vendored
Normal file
66
server/node_modules/busboy/test/test-utils-decoder.js
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
var Decoder = require('../lib/utils').Decoder;
|
||||||
|
|
||||||
|
var path = require('path'),
|
||||||
|
assert = require('assert');
|
||||||
|
|
||||||
|
var group = path.basename(__filename, '.js') + '/';
|
||||||
|
|
||||||
|
[
|
||||||
|
{ source: ['Hello world'],
|
||||||
|
expected: 'Hello world',
|
||||||
|
what: 'No encoded bytes'
|
||||||
|
},
|
||||||
|
{ source: ['Hello%20world'],
|
||||||
|
expected: 'Hello world',
|
||||||
|
what: 'One full encoded byte'
|
||||||
|
},
|
||||||
|
{ source: ['Hello%20world%21'],
|
||||||
|
expected: 'Hello world!',
|
||||||
|
what: 'Two full encoded bytes'
|
||||||
|
},
|
||||||
|
{ source: ['Hello%', '20world'],
|
||||||
|
expected: 'Hello world',
|
||||||
|
what: 'One full encoded byte split #1'
|
||||||
|
},
|
||||||
|
{ source: ['Hello%2', '0world'],
|
||||||
|
expected: 'Hello world',
|
||||||
|
what: 'One full encoded byte split #2'
|
||||||
|
},
|
||||||
|
{ source: ['Hello%20', 'world'],
|
||||||
|
expected: 'Hello world',
|
||||||
|
what: 'One full encoded byte (concat)'
|
||||||
|
},
|
||||||
|
{ source: ['Hello%2Qworld'],
|
||||||
|
expected: 'Hello%2Qworld',
|
||||||
|
what: 'Malformed encoded byte #1'
|
||||||
|
},
|
||||||
|
{ source: ['Hello%world'],
|
||||||
|
expected: 'Hello%world',
|
||||||
|
what: 'Malformed encoded byte #2'
|
||||||
|
},
|
||||||
|
{ source: ['Hello+world'],
|
||||||
|
expected: 'Hello world',
|
||||||
|
what: 'Plus to space'
|
||||||
|
},
|
||||||
|
{ source: ['Hello+world%21'],
|
||||||
|
expected: 'Hello world!',
|
||||||
|
what: 'Plus and encoded byte'
|
||||||
|
},
|
||||||
|
{ source: ['5%2B5%3D10'],
|
||||||
|
expected: '5+5=10',
|
||||||
|
what: 'Encoded plus'
|
||||||
|
},
|
||||||
|
{ source: ['5+%2B+5+%3D+10'],
|
||||||
|
expected: '5 + 5 = 10',
|
||||||
|
what: 'Spaces and encoded plus'
|
||||||
|
},
|
||||||
|
].forEach(function(v) {
|
||||||
|
var dec = new Decoder(), result = '';
|
||||||
|
v.source.forEach(function(s) {
|
||||||
|
result += dec.write(s);
|
||||||
|
});
|
||||||
|
var msg = '[' + group + v.what + ']: decoded string mismatch.\n'
|
||||||
|
+ 'Saw: ' + result + '\n'
|
||||||
|
+ 'Expected: ' + v.expected;
|
||||||
|
assert.deepEqual(result, v.expected, msg);
|
||||||
|
});
|
96
server/node_modules/busboy/test/test-utils-parse-params.js
generated
vendored
Normal file
96
server/node_modules/busboy/test/test-utils-parse-params.js
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
var parseParams = require('../lib/utils').parseParams;
|
||||||
|
|
||||||
|
var path = require('path'),
|
||||||
|
assert = require('assert'),
|
||||||
|
inspect = require('util').inspect;
|
||||||
|
|
||||||
|
var group = path.basename(__filename, '.js') + '/';
|
||||||
|
|
||||||
|
[
|
||||||
|
{ source: 'video/ogg',
|
||||||
|
expected: ['video/ogg'],
|
||||||
|
what: 'No parameters'
|
||||||
|
},
|
||||||
|
{ source: 'video/ogg;',
|
||||||
|
expected: ['video/ogg'],
|
||||||
|
what: 'No parameters (with separator)'
|
||||||
|
},
|
||||||
|
{ source: 'video/ogg; ',
|
||||||
|
expected: ['video/ogg'],
|
||||||
|
what: 'No parameters (with separator followed by whitespace)'
|
||||||
|
},
|
||||||
|
{ source: ';video/ogg',
|
||||||
|
expected: ['', 'video/ogg'],
|
||||||
|
what: 'Empty parameter'
|
||||||
|
},
|
||||||
|
{ source: 'video/*',
|
||||||
|
expected: ['video/*'],
|
||||||
|
what: 'Subtype with asterisk'
|
||||||
|
},
|
||||||
|
{ source: 'text/plain; encoding=utf8',
|
||||||
|
expected: ['text/plain', ['encoding', 'utf8']],
|
||||||
|
what: 'Unquoted'
|
||||||
|
},
|
||||||
|
{ source: 'text/plain; encoding=',
|
||||||
|
expected: ['text/plain', ['encoding', '']],
|
||||||
|
what: 'Unquoted empty string'
|
||||||
|
},
|
||||||
|
{ source: 'text/plain; encoding="utf8"',
|
||||||
|
expected: ['text/plain', ['encoding', 'utf8']],
|
||||||
|
what: 'Quoted'
|
||||||
|
},
|
||||||
|
{ source: 'text/plain; greeting="hello \\"world\\""',
|
||||||
|
expected: ['text/plain', ['greeting', 'hello "world"']],
|
||||||
|
what: 'Quotes within quoted'
|
||||||
|
},
|
||||||
|
{ source: 'text/plain; encoding=""',
|
||||||
|
expected: ['text/plain', ['encoding', '']],
|
||||||
|
what: 'Quoted empty string'
|
||||||
|
},
|
||||||
|
{ source: 'text/plain; encoding="utf8";\t foo=bar;test',
|
||||||
|
expected: ['text/plain', ['encoding', 'utf8'], ['foo', 'bar'], 'test'],
|
||||||
|
what: 'Multiple params with various spacing'
|
||||||
|
},
|
||||||
|
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates",
|
||||||
|
expected: ['text/plain', ['filename', '£ rates']],
|
||||||
|
what: 'Extended parameter (RFC 5987) with language'
|
||||||
|
},
|
||||||
|
{ source: "text/plain; filename*=utf-8''%c2%a3%20and%20%e2%82%ac%20rates",
|
||||||
|
expected: ['text/plain', ['filename', '£ and € rates']],
|
||||||
|
what: 'Extended parameter (RFC 5987) without language'
|
||||||
|
},
|
||||||
|
{ source: "text/plain; filename*=utf-8''%E6%B5%8B%E8%AF%95%E6%96%87%E6%A1%A3",
|
||||||
|
expected: ['text/plain', ['filename', '测试文档']],
|
||||||
|
what: 'Extended parameter (RFC 5987) without language #2'
|
||||||
|
},
|
||||||
|
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates; altfilename*=utf-8''%c2%a3%20and%20%e2%82%ac%20rates",
|
||||||
|
expected: ['text/plain', ['filename', '£ rates'], ['altfilename', '£ and € rates']],
|
||||||
|
what: 'Multiple extended parameters (RFC 5987) with mixed charsets'
|
||||||
|
},
|
||||||
|
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates; altfilename=\"foobarbaz\"",
|
||||||
|
expected: ['text/plain', ['filename', '£ rates'], ['altfilename', 'foobarbaz']],
|
||||||
|
what: 'Mixed regular and extended parameters (RFC 5987)'
|
||||||
|
},
|
||||||
|
{ source: "text/plain; filename=\"foobarbaz\"; altfilename*=iso-8859-1'en'%A3%20rates",
|
||||||
|
expected: ['text/plain', ['filename', 'foobarbaz'], ['altfilename', '£ rates']],
|
||||||
|
what: 'Mixed regular and extended parameters (RFC 5987) #2'
|
||||||
|
},
|
||||||
|
{ source: 'text/plain; filename="C:\\folder\\test.png"',
|
||||||
|
expected: ['text/plain', ['filename', 'C:\\folder\\test.png']],
|
||||||
|
what: 'Unescaped backslashes should be considered backslashes'
|
||||||
|
},
|
||||||
|
{ source: 'text/plain; filename="John \\"Magic\\" Smith.png"',
|
||||||
|
expected: ['text/plain', ['filename', 'John "Magic" Smith.png']],
|
||||||
|
what: 'Escaped double-quotes should be considered double-quotes'
|
||||||
|
},
|
||||||
|
{ source: 'multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY',
|
||||||
|
expected: ['multipart/form-data', ['charset', 'utf-8'], ['boundary', '0xKhTmLbOuNdArY']],
|
||||||
|
what: 'Multiple non-quoted parameters'
|
||||||
|
},
|
||||||
|
].forEach(function(v) {
|
||||||
|
var result = parseParams(v.source),
|
||||||
|
msg = '[' + group + v.what + ']: parsed parameters mismatch.\n'
|
||||||
|
+ 'Saw: ' + inspect(result) + '\n'
|
||||||
|
+ 'Expected: ' + inspect(v.expected);
|
||||||
|
assert.deepEqual(result, v.expected, msg);
|
||||||
|
});
|
4
server/node_modules/busboy/test/test.js
generated
vendored
Normal file
4
server/node_modules/busboy/test/test.js
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
require('fs').readdirSync(__dirname).forEach(function(f) {
|
||||||
|
if (f.substr(0, 5) === 'test-')
|
||||||
|
require('./' + f);
|
||||||
|
});
|
16
server/node_modules/dicer/.travis.yml
generated
vendored
Normal file
16
server/node_modules/dicer/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
sudo: false
|
||||||
|
language: cpp
|
||||||
|
notifications:
|
||||||
|
email: false
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- TRAVIS_NODE_VERSION="4"
|
||||||
|
- TRAVIS_NODE_VERSION="6"
|
||||||
|
- TRAVIS_NODE_VERSION="8"
|
||||||
|
- TRAVIS_NODE_VERSION="10"
|
||||||
|
install:
|
||||||
|
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
|
||||||
|
- node --version
|
||||||
|
- npm --version
|
||||||
|
- npm install
|
||||||
|
script: npm test
|
19
server/node_modules/dicer/LICENSE
generated
vendored
Normal file
19
server/node_modules/dicer/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright Brian White. All rights reserved.
|
||||||
|
|
||||||
|
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.
|
122
server/node_modules/dicer/README.md
generated
vendored
Normal file
122
server/node_modules/dicer/README.md
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
Description
|
||||||
|
===========
|
||||||
|
|
||||||
|
A very fast streaming multipart parser for node.js.
|
||||||
|
|
||||||
|
Benchmarks can be found [here](https://github.com/mscdex/dicer/wiki/Benchmarks).
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
============
|
||||||
|
|
||||||
|
* [node.js](http://nodejs.org/) -- v4.5.0 or newer
|
||||||
|
|
||||||
|
|
||||||
|
Install
|
||||||
|
============
|
||||||
|
|
||||||
|
npm install dicer
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
========
|
||||||
|
|
||||||
|
* Parse an HTTP form upload
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
var inspect = require('util').inspect,
|
||||||
|
http = require('http');
|
||||||
|
|
||||||
|
var Dicer = require('dicer');
|
||||||
|
|
||||||
|
// quick and dirty way to parse multipart boundary
|
||||||
|
var RE_BOUNDARY = /^multipart\/.+?(?:; boundary=(?:(?:"(.+)")|(?:([^\s]+))))$/i,
|
||||||
|
HTML = Buffer.from('<html><head></head><body>\
|
||||||
|
<form method="POST" enctype="multipart/form-data">\
|
||||||
|
<input type="text" name="textfield"><br />\
|
||||||
|
<input type="file" name="filefield"><br />\
|
||||||
|
<input type="submit">\
|
||||||
|
</form>\
|
||||||
|
</body></html>'),
|
||||||
|
PORT = 8080;
|
||||||
|
|
||||||
|
http.createServer(function(req, res) {
|
||||||
|
var m;
|
||||||
|
if (req.method === 'POST'
|
||||||
|
&& req.headers['content-type']
|
||||||
|
&& (m = RE_BOUNDARY.exec(req.headers['content-type']))) {
|
||||||
|
var d = new Dicer({ boundary: m[1] || m[2] });
|
||||||
|
|
||||||
|
d.on('part', function(p) {
|
||||||
|
console.log('New part!');
|
||||||
|
p.on('header', function(header) {
|
||||||
|
for (var h in header) {
|
||||||
|
console.log('Part header: k: ' + inspect(h)
|
||||||
|
+ ', v: ' + inspect(header[h]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
p.on('data', function(data) {
|
||||||
|
console.log('Part data: ' + inspect(data.toString()));
|
||||||
|
});
|
||||||
|
p.on('end', function() {
|
||||||
|
console.log('End of part\n');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
d.on('finish', function() {
|
||||||
|
console.log('End of parts');
|
||||||
|
res.writeHead(200);
|
||||||
|
res.end('Form submission successful!');
|
||||||
|
});
|
||||||
|
req.pipe(d);
|
||||||
|
} else if (req.method === 'GET' && req.url === '/') {
|
||||||
|
res.writeHead(200);
|
||||||
|
res.end(HTML);
|
||||||
|
} else {
|
||||||
|
res.writeHead(404);
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
}).listen(PORT, function() {
|
||||||
|
console.log('Listening for requests on port ' + PORT);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
API
|
||||||
|
===
|
||||||
|
|
||||||
|
_Dicer_ is a _WritableStream_
|
||||||
|
|
||||||
|
Dicer (special) events
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
* **finish**() - Emitted when all parts have been parsed and the Dicer instance has been ended.
|
||||||
|
|
||||||
|
* **part**(< _PartStream_ >stream) - Emitted when a new part has been found.
|
||||||
|
|
||||||
|
* **preamble**(< _PartStream_ >stream) - Emitted for preamble if you should happen to need it (can usually be ignored).
|
||||||
|
|
||||||
|
* **trailer**(< _Buffer_ >data) - Emitted when trailing data was found after the terminating boundary (as with the preamble, this can usually be ignored too).
|
||||||
|
|
||||||
|
|
||||||
|
Dicer methods
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* **(constructor)**(< _object_ >config) - Creates and returns a new Dicer instance with the following valid `config` settings:
|
||||||
|
|
||||||
|
* **boundary** - _string_ - This is the boundary used to detect the beginning of a new part.
|
||||||
|
|
||||||
|
* **headerFirst** - _boolean_ - If true, preamble header parsing will be performed first.
|
||||||
|
|
||||||
|
* **maxHeaderPairs** - _integer_ - The maximum number of header key=>value pairs to parse **Default:** 2000 (same as node's http).
|
||||||
|
|
||||||
|
* **setBoundary**(< _string_ >boundary) - _(void)_ - Sets the boundary to use for parsing and performs some initialization needed for parsing. You should only need to use this if you set `headerFirst` to true in the constructor and are parsing the boundary from the preamble header.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_PartStream_ is a _ReadableStream_
|
||||||
|
|
||||||
|
PartStream (special) events
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* **header**(< _object_ >header) - An object containing the header for this particular part. Each property value is an _array_ of one or more string values.
|
63
server/node_modules/dicer/bench/dicer-bench-multipart-parser.js
generated
vendored
Normal file
63
server/node_modules/dicer/bench/dicer-bench-multipart-parser.js
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
var assert = require('assert');
|
||||||
|
var Dicer = require('..'),
|
||||||
|
boundary = '-----------------------------168072824752491622650073',
|
||||||
|
d = new Dicer({ boundary: boundary }),
|
||||||
|
mb = 100,
|
||||||
|
buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
|
||||||
|
callbacks =
|
||||||
|
{ partBegin: -1,
|
||||||
|
partEnd: -1,
|
||||||
|
headerField: -1,
|
||||||
|
headerValue: -1,
|
||||||
|
partData: -1,
|
||||||
|
end: -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
d.on('part', function(p) {
|
||||||
|
callbacks.partBegin++;
|
||||||
|
p.on('header', function(header) {
|
||||||
|
/*for (var h in header)
|
||||||
|
console.log('Part header: k: ' + inspect(h) + ', v: ' + inspect(header[h]));*/
|
||||||
|
});
|
||||||
|
p.on('data', function(data) {
|
||||||
|
callbacks.partData++;
|
||||||
|
//console.log('Part data: ' + inspect(data.toString()));
|
||||||
|
});
|
||||||
|
p.on('end', function() {
|
||||||
|
//console.log('End of part\n');
|
||||||
|
callbacks.partEnd++;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
d.on('end', function() {
|
||||||
|
//console.log('End of parts');
|
||||||
|
callbacks.end++;
|
||||||
|
});
|
||||||
|
|
||||||
|
var start = +new Date(),
|
||||||
|
nparsed = d.write(buffer),
|
||||||
|
duration = +new Date - start,
|
||||||
|
mbPerSec = (mb / (duration / 1000)).toFixed(2);
|
||||||
|
|
||||||
|
console.log(mbPerSec+' mb/sec');
|
||||||
|
|
||||||
|
//assert.equal(nparsed, buffer.length);
|
||||||
|
|
||||||
|
function createMultipartBuffer(boundary, size) {
|
||||||
|
var head =
|
||||||
|
'--'+boundary+'\r\n'
|
||||||
|
+ 'content-disposition: form-data; name="field1"\r\n'
|
||||||
|
+ '\r\n'
|
||||||
|
, tail = '\r\n--'+boundary+'--\r\n'
|
||||||
|
, buffer = Buffer.allocUnsafe(size);
|
||||||
|
|
||||||
|
buffer.write(head, 'ascii', 0);
|
||||||
|
buffer.write(tail, 'ascii', buffer.length - tail.length);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
/*for (var k in callbacks) {
|
||||||
|
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
|
||||||
|
}*/
|
||||||
|
});
|
70
server/node_modules/dicer/bench/formidable-bench-multipart-parser.js
generated
vendored
Normal file
70
server/node_modules/dicer/bench/formidable-bench-multipart-parser.js
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
var assert = require('assert');
|
||||||
|
require('../node_modules/formidable/test/common');
|
||||||
|
var multipartParser = require('../node_modules/formidable/lib/multipart_parser'),
|
||||||
|
MultipartParser = multipartParser.MultipartParser,
|
||||||
|
parser = new MultipartParser(),
|
||||||
|
boundary = '-----------------------------168072824752491622650073',
|
||||||
|
mb = 100,
|
||||||
|
buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
|
||||||
|
callbacks =
|
||||||
|
{ partBegin: -1,
|
||||||
|
partEnd: -1,
|
||||||
|
headerField: -1,
|
||||||
|
headerValue: -1,
|
||||||
|
partData: -1,
|
||||||
|
end: -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
parser.initWithBoundary(boundary);
|
||||||
|
parser.onHeaderField = function() {
|
||||||
|
callbacks.headerField++;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.onHeaderValue = function() {
|
||||||
|
callbacks.headerValue++;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.onPartBegin = function() {
|
||||||
|
callbacks.partBegin++;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.onPartData = function() {
|
||||||
|
callbacks.partData++;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.onPartEnd = function() {
|
||||||
|
callbacks.partEnd++;
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.onEnd = function() {
|
||||||
|
callbacks.end++;
|
||||||
|
};
|
||||||
|
|
||||||
|
var start = +new Date(),
|
||||||
|
nparsed = parser.write(buffer),
|
||||||
|
duration = +new Date - start,
|
||||||
|
mbPerSec = (mb / (duration / 1000)).toFixed(2);
|
||||||
|
|
||||||
|
console.log(mbPerSec+' mb/sec');
|
||||||
|
|
||||||
|
//assert.equal(nparsed, buffer.length);
|
||||||
|
|
||||||
|
function createMultipartBuffer(boundary, size) {
|
||||||
|
var head =
|
||||||
|
'--'+boundary+'\r\n'
|
||||||
|
+ 'content-disposition: form-data; name="field1"\r\n'
|
||||||
|
+ '\r\n'
|
||||||
|
, tail = '\r\n--'+boundary+'--\r\n'
|
||||||
|
, buffer = Buffer.allocUnsafe(size);
|
||||||
|
|
||||||
|
buffer.write(head, 'ascii', 0);
|
||||||
|
buffer.write(tail, 'ascii', buffer.length - tail.length);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
/*for (var k in callbacks) {
|
||||||
|
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
|
||||||
|
}*/
|
||||||
|
});
|
56
server/node_modules/dicer/bench/multipartser-bench-multipart-parser.js
generated
vendored
Normal file
56
server/node_modules/dicer/bench/multipartser-bench-multipart-parser.js
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
var assert = require('assert');
|
||||||
|
var multipartser = require('multipartser'),
|
||||||
|
boundary = '-----------------------------168072824752491622650073',
|
||||||
|
parser = multipartser(),
|
||||||
|
mb = 100,
|
||||||
|
buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
|
||||||
|
callbacks =
|
||||||
|
{ partBegin: -1,
|
||||||
|
partEnd: -1,
|
||||||
|
headerField: -1,
|
||||||
|
headerValue: -1,
|
||||||
|
partData: -1,
|
||||||
|
end: -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.boundary( boundary );
|
||||||
|
|
||||||
|
parser.on( 'part', function ( part ) {
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on( 'end', function () {
|
||||||
|
//console.log( 'completed parsing' );
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on( 'error', function ( error ) {
|
||||||
|
console.error( error );
|
||||||
|
});
|
||||||
|
|
||||||
|
var start = +new Date(),
|
||||||
|
nparsed = parser.data(buffer),
|
||||||
|
nend = parser.end(),
|
||||||
|
duration = +new Date - start,
|
||||||
|
mbPerSec = (mb / (duration / 1000)).toFixed(2);
|
||||||
|
|
||||||
|
console.log(mbPerSec+' mb/sec');
|
||||||
|
|
||||||
|
//assert.equal(nparsed, buffer.length);
|
||||||
|
|
||||||
|
function createMultipartBuffer(boundary, size) {
|
||||||
|
var head =
|
||||||
|
'--'+boundary+'\r\n'
|
||||||
|
+ 'content-disposition: form-data; name="field1"\r\n'
|
||||||
|
+ '\r\n'
|
||||||
|
, tail = '\r\n--'+boundary+'--\r\n'
|
||||||
|
, buffer = Buffer.allocUnsafe(size);
|
||||||
|
|
||||||
|
buffer.write(head, 'ascii', 0);
|
||||||
|
buffer.write(tail, 'ascii', buffer.length - tail.length);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
/*for (var k in callbacks) {
|
||||||
|
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
|
||||||
|
}*/
|
||||||
|
});
|
76
server/node_modules/dicer/bench/multiparty-bench-multipart-parser.js
generated
vendored
Normal file
76
server/node_modules/dicer/bench/multiparty-bench-multipart-parser.js
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
var assert = require('assert'),
|
||||||
|
Form = require('multiparty').Form,
|
||||||
|
boundary = '-----------------------------168072824752491622650073',
|
||||||
|
mb = 100,
|
||||||
|
buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
|
||||||
|
callbacks =
|
||||||
|
{ partBegin: -1,
|
||||||
|
partEnd: -1,
|
||||||
|
headerField: -1,
|
||||||
|
headerValue: -1,
|
||||||
|
partData: -1,
|
||||||
|
end: -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
var form = new Form({ boundary: boundary });
|
||||||
|
|
||||||
|
hijack('onParseHeaderField', function() {
|
||||||
|
callbacks.headerField++;
|
||||||
|
});
|
||||||
|
|
||||||
|
hijack('onParseHeaderValue', function() {
|
||||||
|
callbacks.headerValue++;
|
||||||
|
});
|
||||||
|
|
||||||
|
hijack('onParsePartBegin', function() {
|
||||||
|
callbacks.partBegin++;
|
||||||
|
});
|
||||||
|
|
||||||
|
hijack('onParsePartData', function() {
|
||||||
|
callbacks.partData++;
|
||||||
|
});
|
||||||
|
|
||||||
|
hijack('onParsePartEnd', function() {
|
||||||
|
callbacks.partEnd++;
|
||||||
|
});
|
||||||
|
|
||||||
|
form.on('finish', function() {
|
||||||
|
callbacks.end++;
|
||||||
|
});
|
||||||
|
|
||||||
|
var start = new Date();
|
||||||
|
form.write(buffer, function(err) {
|
||||||
|
var duration = new Date() - start;
|
||||||
|
assert.ifError(err);
|
||||||
|
var mbPerSec = (mb / (duration / 1000)).toFixed(2);
|
||||||
|
console.log(mbPerSec+' mb/sec');
|
||||||
|
});
|
||||||
|
|
||||||
|
//assert.equal(nparsed, buffer.length);
|
||||||
|
|
||||||
|
function createMultipartBuffer(boundary, size) {
|
||||||
|
var head =
|
||||||
|
'--'+boundary+'\r\n'
|
||||||
|
+ 'content-disposition: form-data; name="field1"\r\n'
|
||||||
|
+ '\r\n'
|
||||||
|
, tail = '\r\n--'+boundary+'--\r\n'
|
||||||
|
, buffer = Buffer.allocUnsafe(size);
|
||||||
|
|
||||||
|
buffer.write(head, 'ascii', 0);
|
||||||
|
buffer.write(tail, 'ascii', buffer.length - tail.length);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
/*for (var k in callbacks) {
|
||||||
|
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
|
||||||
|
}*/
|
||||||
|
});
|
||||||
|
|
||||||
|
function hijack(name, fn) {
|
||||||
|
var oldFn = form[name];
|
||||||
|
form[name] = function() {
|
||||||
|
fn();
|
||||||
|
return oldFn.apply(this, arguments);
|
||||||
|
};
|
||||||
|
}
|
63
server/node_modules/dicer/bench/parted-bench-multipart-parser.js
generated
vendored
Normal file
63
server/node_modules/dicer/bench/parted-bench-multipart-parser.js
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// A special, edited version of the multipart parser from parted is needed here
|
||||||
|
// because otherwise it attempts to do some things above and beyond just parsing
|
||||||
|
// -- like saving to disk and whatnot
|
||||||
|
|
||||||
|
var assert = require('assert');
|
||||||
|
var Parser = require('./parted-multipart'),
|
||||||
|
boundary = '-----------------------------168072824752491622650073',
|
||||||
|
parser = new Parser('boundary=' + boundary),
|
||||||
|
mb = 100,
|
||||||
|
buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
|
||||||
|
callbacks =
|
||||||
|
{ partBegin: -1,
|
||||||
|
partEnd: -1,
|
||||||
|
headerField: -1,
|
||||||
|
headerValue: -1,
|
||||||
|
partData: -1,
|
||||||
|
end: -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
parser.on('header', function() {
|
||||||
|
//callbacks.headerField++;
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on('data', function() {
|
||||||
|
//callbacks.partBegin++;
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on('part', function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on('end', function() {
|
||||||
|
//callbacks.end++;
|
||||||
|
});
|
||||||
|
|
||||||
|
var start = +new Date(),
|
||||||
|
nparsed = parser.write(buffer),
|
||||||
|
duration = +new Date - start,
|
||||||
|
mbPerSec = (mb / (duration / 1000)).toFixed(2);
|
||||||
|
|
||||||
|
console.log(mbPerSec+' mb/sec');
|
||||||
|
|
||||||
|
//assert.equal(nparsed, buffer.length);
|
||||||
|
|
||||||
|
function createMultipartBuffer(boundary, size) {
|
||||||
|
var head =
|
||||||
|
'--'+boundary+'\r\n'
|
||||||
|
+ 'content-disposition: form-data; name="field1"\r\n'
|
||||||
|
+ '\r\n'
|
||||||
|
, tail = '\r\n--'+boundary+'--\r\n'
|
||||||
|
, buffer = Buffer.allocUnsafe(size);
|
||||||
|
|
||||||
|
buffer.write(head, 'ascii', 0);
|
||||||
|
buffer.write(tail, 'ascii', buffer.length - tail.length);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
/*for (var k in callbacks) {
|
||||||
|
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
|
||||||
|
}*/
|
||||||
|
});
|
485
server/node_modules/dicer/bench/parted-multipart.js
generated
vendored
Normal file
485
server/node_modules/dicer/bench/parted-multipart.js
generated
vendored
Normal file
@ -0,0 +1,485 @@
|
|||||||
|
/**
|
||||||
|
* Parted (https://github.com/chjj/parted)
|
||||||
|
* A streaming multipart state parser.
|
||||||
|
* Copyright (c) 2011, Christopher Jeffrey. (MIT Licensed)
|
||||||
|
*/
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, path = require('path')
|
||||||
|
, EventEmitter = require('events').EventEmitter
|
||||||
|
, StringDecoder = require('string_decoder').StringDecoder
|
||||||
|
, set = require('qs').set
|
||||||
|
, each = Array.prototype.forEach;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Character Constants
|
||||||
|
*/
|
||||||
|
|
||||||
|
var DASH = '-'.charCodeAt(0)
|
||||||
|
, CR = '\r'.charCodeAt(0)
|
||||||
|
, LF = '\n'.charCodeAt(0)
|
||||||
|
, COLON = ':'.charCodeAt(0)
|
||||||
|
, SPACE = ' '.charCodeAt(0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parser
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Parser = function(type, options) {
|
||||||
|
if (!(this instanceof Parser)) {
|
||||||
|
return new Parser(type, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventEmitter.call(this);
|
||||||
|
|
||||||
|
this.writable = true;
|
||||||
|
this.readable = true;
|
||||||
|
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
var key = grab(type, 'boundary');
|
||||||
|
if (!key) {
|
||||||
|
return this._error('No boundary key found.');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.key = Buffer.allocUnsafe('\r\n--' + key);
|
||||||
|
|
||||||
|
this._key = {};
|
||||||
|
each.call(this.key, function(ch) {
|
||||||
|
this._key[ch] = true;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
this.state = 'start';
|
||||||
|
this.pending = 0;
|
||||||
|
this.written = 0;
|
||||||
|
this.writtenDisk = 0;
|
||||||
|
this.buff = Buffer.allocUnsafe(200);
|
||||||
|
|
||||||
|
this.preamble = true;
|
||||||
|
this.epilogue = false;
|
||||||
|
|
||||||
|
this._reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.__proto__ = EventEmitter.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsing
|
||||||
|
*/
|
||||||
|
|
||||||
|
Parser.prototype.write = function(data) {
|
||||||
|
if (!this.writable
|
||||||
|
|| this.epilogue) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._parse(data);
|
||||||
|
} catch (e) {
|
||||||
|
this._error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.end = function(data) {
|
||||||
|
if (!this.writable) return;
|
||||||
|
|
||||||
|
if (data) this.write(data);
|
||||||
|
|
||||||
|
if (!this.epilogue) {
|
||||||
|
return this._error('Message underflow.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype._parse = function(data) {
|
||||||
|
var i = 0
|
||||||
|
, len = data.length
|
||||||
|
, buff = this.buff
|
||||||
|
, key = this.key
|
||||||
|
, ch
|
||||||
|
, val
|
||||||
|
, j;
|
||||||
|
|
||||||
|
for (; i < len; i++) {
|
||||||
|
if (this.pos >= 200) {
|
||||||
|
return this._error('Potential buffer overflow.');
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = data[i];
|
||||||
|
|
||||||
|
switch (this.state) {
|
||||||
|
case 'start':
|
||||||
|
switch (ch) {
|
||||||
|
case DASH:
|
||||||
|
this.pos = 3;
|
||||||
|
this.state = 'key';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'key':
|
||||||
|
if (this.pos === key.length) {
|
||||||
|
this.state = 'key_end';
|
||||||
|
i--;
|
||||||
|
} else if (ch !== key[this.pos]) {
|
||||||
|
if (this.preamble) {
|
||||||
|
this.state = 'start';
|
||||||
|
i--;
|
||||||
|
} else {
|
||||||
|
this.state = 'body';
|
||||||
|
val = this.pos - i;
|
||||||
|
if (val > 0) {
|
||||||
|
this._write(key.slice(0, val));
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.pos++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'key_end':
|
||||||
|
switch (ch) {
|
||||||
|
case CR:
|
||||||
|
this.state = 'key_line_end';
|
||||||
|
break;
|
||||||
|
case DASH:
|
||||||
|
this.state = 'key_dash_end';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return this._error('Expected CR or DASH.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'key_line_end':
|
||||||
|
switch (ch) {
|
||||||
|
case LF:
|
||||||
|
if (this.preamble) {
|
||||||
|
this.preamble = false;
|
||||||
|
} else {
|
||||||
|
this._finish();
|
||||||
|
}
|
||||||
|
this.state = 'header_name';
|
||||||
|
this.pos = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return this._error('Expected CR.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'key_dash_end':
|
||||||
|
switch (ch) {
|
||||||
|
case DASH:
|
||||||
|
this.epilogue = true;
|
||||||
|
this._finish();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
return this._error('Expected DASH.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'header_name':
|
||||||
|
switch (ch) {
|
||||||
|
case COLON:
|
||||||
|
this.header = buff.toString('ascii', 0, this.pos);
|
||||||
|
this.pos = 0;
|
||||||
|
this.state = 'header_val';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buff[this.pos++] = ch | 32;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'header_val':
|
||||||
|
switch (ch) {
|
||||||
|
case CR:
|
||||||
|
this.state = 'header_val_end';
|
||||||
|
break;
|
||||||
|
case SPACE:
|
||||||
|
if (this.pos === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
; // FALL-THROUGH
|
||||||
|
default:
|
||||||
|
buff[this.pos++] = ch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'header_val_end':
|
||||||
|
switch (ch) {
|
||||||
|
case LF:
|
||||||
|
val = buff.toString('ascii', 0, this.pos);
|
||||||
|
this._header(this.header, val);
|
||||||
|
this.pos = 0;
|
||||||
|
this.state = 'header_end';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return this._error('Expected LF.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'header_end':
|
||||||
|
switch (ch) {
|
||||||
|
case CR:
|
||||||
|
this.state = 'head_end';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.state = 'header_name';
|
||||||
|
i--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'head_end':
|
||||||
|
switch (ch) {
|
||||||
|
case LF:
|
||||||
|
this.state = 'body';
|
||||||
|
i++;
|
||||||
|
if (i >= len) return;
|
||||||
|
data = data.slice(i);
|
||||||
|
i = -1;
|
||||||
|
len = data.length;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return this._error('Expected LF.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'body':
|
||||||
|
switch (ch) {
|
||||||
|
case CR:
|
||||||
|
if (i > 0) {
|
||||||
|
this._write(data.slice(0, i));
|
||||||
|
}
|
||||||
|
this.pos = 1;
|
||||||
|
this.state = 'key';
|
||||||
|
data = data.slice(i);
|
||||||
|
i = 0;
|
||||||
|
len = data.length;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// boyer-moore-like algorithm
|
||||||
|
// at felixge's suggestion
|
||||||
|
while ((j = i + key.length - 1) < len) {
|
||||||
|
if (this._key[data[j]]) break;
|
||||||
|
i = j;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.state === 'body') {
|
||||||
|
this._write(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype._header = function(name, val) {
|
||||||
|
/*if (name === 'content-disposition') {
|
||||||
|
this.field = grab(val, 'name');
|
||||||
|
this.file = grab(val, 'filename');
|
||||||
|
|
||||||
|
if (this.file) {
|
||||||
|
this.data = stream(this.file, this.options.path);
|
||||||
|
} else {
|
||||||
|
this.decode = new StringDecoder('utf8');
|
||||||
|
this.data = '';
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return this.emit('header', name, val);
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype._write = function(data) {
|
||||||
|
/*if (this.data == null) {
|
||||||
|
return this._error('No disposition.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.file) {
|
||||||
|
this.data.write(data);
|
||||||
|
this.writtenDisk += data.length;
|
||||||
|
} else {
|
||||||
|
this.data += this.decode.write(data);
|
||||||
|
this.written += data.length;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
this.emit('data', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype._reset = function() {
|
||||||
|
this.pos = 0;
|
||||||
|
this.decode = null;
|
||||||
|
this.field = null;
|
||||||
|
this.data = null;
|
||||||
|
this.file = null;
|
||||||
|
this.header = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype._error = function(err) {
|
||||||
|
this.destroy();
|
||||||
|
this.emit('error', typeof err === 'string'
|
||||||
|
? new Error(err)
|
||||||
|
: err);
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.destroy = function(err) {
|
||||||
|
this.writable = false;
|
||||||
|
this.readable = false;
|
||||||
|
this._reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype._finish = function() {
|
||||||
|
var self = this
|
||||||
|
, field = this.field
|
||||||
|
, data = this.data
|
||||||
|
, file = this.file
|
||||||
|
, part;
|
||||||
|
|
||||||
|
this.pending++;
|
||||||
|
|
||||||
|
this._reset();
|
||||||
|
|
||||||
|
if (data && data.path) {
|
||||||
|
part = data.path;
|
||||||
|
data.end(next);
|
||||||
|
} else {
|
||||||
|
part = data;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (!self.readable) return;
|
||||||
|
|
||||||
|
self.pending--;
|
||||||
|
|
||||||
|
self.emit('part', field, part);
|
||||||
|
|
||||||
|
if (data && data.path) {
|
||||||
|
self.emit('file', field, part, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.epilogue && !self.pending) {
|
||||||
|
self.emit('end');
|
||||||
|
self.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads
|
||||||
|
*/
|
||||||
|
|
||||||
|
Parser.root = process.platform === 'win32'
|
||||||
|
? 'C:/Temp'
|
||||||
|
: '/tmp';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Middleware
|
||||||
|
*/
|
||||||
|
|
||||||
|
Parser.middleware = function(options) {
|
||||||
|
options = options || {};
|
||||||
|
return function(req, res, next) {
|
||||||
|
if (options.ensureBody) {
|
||||||
|
req.body = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.method === 'GET'
|
||||||
|
|| req.method === 'HEAD'
|
||||||
|
|| req._multipart) return next();
|
||||||
|
|
||||||
|
req._multipart = true;
|
||||||
|
|
||||||
|
var type = req.headers['content-type'];
|
||||||
|
|
||||||
|
if (type) type = type.split(';')[0].trim().toLowerCase();
|
||||||
|
|
||||||
|
if (type === 'multipart/form-data') {
|
||||||
|
Parser.handle(req, res, next, options);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler
|
||||||
|
*/
|
||||||
|
|
||||||
|
Parser.handle = function(req, res, next, options) {
|
||||||
|
var parser = new Parser(req.headers['content-type'], options)
|
||||||
|
, diskLimit = options.diskLimit
|
||||||
|
, limit = options.limit
|
||||||
|
, parts = {}
|
||||||
|
, files = {};
|
||||||
|
|
||||||
|
parser.on('error', function(err) {
|
||||||
|
req.destroy();
|
||||||
|
next(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on('part', function(field, part) {
|
||||||
|
set(parts, field, part);
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on('file', function(field, path, name) {
|
||||||
|
set(files, field, {
|
||||||
|
path: path,
|
||||||
|
name: name,
|
||||||
|
toString: function() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on('data', function() {
|
||||||
|
if (this.writtenDisk > diskLimit || this.written > limit) {
|
||||||
|
this.emit('error', new Error('Overflow.'));
|
||||||
|
this.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
parser.on('end', next);
|
||||||
|
|
||||||
|
req.body = parts;
|
||||||
|
req.files = files;
|
||||||
|
req.pipe(parser);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helpers
|
||||||
|
*/
|
||||||
|
|
||||||
|
var isWindows = process.platform === 'win32';
|
||||||
|
|
||||||
|
var stream = function(name, dir) {
|
||||||
|
var ext = path.extname(name) || ''
|
||||||
|
, name = path.basename(name, ext) || ''
|
||||||
|
, dir = dir || Parser.root
|
||||||
|
, tag;
|
||||||
|
|
||||||
|
tag = Math.random().toString(36).substring(2);
|
||||||
|
|
||||||
|
name = name.substring(0, 200) + '.' + tag;
|
||||||
|
name = path.join(dir, name) + ext.substring(0, 6);
|
||||||
|
name = name.replace(/\0/g, '');
|
||||||
|
|
||||||
|
if (isWindows) {
|
||||||
|
name = name.replace(/[:*<>|"?]/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.createWriteStream(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
var grab = function(str, name) {
|
||||||
|
if (!str) return;
|
||||||
|
|
||||||
|
var rx = new RegExp('\\b' + name + '\\s*=\\s*("[^"]+"|\'[^\']+\'|[^;,]+)', 'i')
|
||||||
|
, cap = rx.exec(str);
|
||||||
|
|
||||||
|
if (cap) {
|
||||||
|
return cap[1].trim().replace(/^['"]|['"]$/g, '');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = Parser;
|
239
server/node_modules/dicer/lib/Dicer.js
generated
vendored
Normal file
239
server/node_modules/dicer/lib/Dicer.js
generated
vendored
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
var WritableStream = require('stream').Writable,
|
||||||
|
inherits = require('util').inherits;
|
||||||
|
|
||||||
|
var StreamSearch = require('streamsearch');
|
||||||
|
|
||||||
|
var PartStream = require('./PartStream'),
|
||||||
|
HeaderParser = require('./HeaderParser');
|
||||||
|
|
||||||
|
var DASH = 45,
|
||||||
|
B_ONEDASH = Buffer.from('-'),
|
||||||
|
B_CRLF = Buffer.from('\r\n'),
|
||||||
|
EMPTY_FN = function() {};
|
||||||
|
|
||||||
|
function Dicer(cfg) {
|
||||||
|
if (!(this instanceof Dicer))
|
||||||
|
return new Dicer(cfg);
|
||||||
|
WritableStream.call(this, cfg);
|
||||||
|
|
||||||
|
if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string'))
|
||||||
|
throw new TypeError('Boundary required');
|
||||||
|
|
||||||
|
if (typeof cfg.boundary === 'string')
|
||||||
|
this.setBoundary(cfg.boundary);
|
||||||
|
else
|
||||||
|
this._bparser = undefined;
|
||||||
|
|
||||||
|
this._headerFirst = cfg.headerFirst;
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this._dashes = 0;
|
||||||
|
this._parts = 0;
|
||||||
|
this._finished = false;
|
||||||
|
this._realFinish = false;
|
||||||
|
this._isPreamble = true;
|
||||||
|
this._justMatched = false;
|
||||||
|
this._firstWrite = true;
|
||||||
|
this._inHeader = true;
|
||||||
|
this._part = undefined;
|
||||||
|
this._cb = undefined;
|
||||||
|
this._ignoreData = false;
|
||||||
|
this._partOpts = (typeof cfg.partHwm === 'number'
|
||||||
|
? { highWaterMark: cfg.partHwm }
|
||||||
|
: {});
|
||||||
|
this._pause = false;
|
||||||
|
|
||||||
|
this._hparser = new HeaderParser(cfg);
|
||||||
|
this._hparser.on('header', function(header) {
|
||||||
|
self._inHeader = false;
|
||||||
|
self._part.emit('header', header);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
inherits(Dicer, WritableStream);
|
||||||
|
|
||||||
|
Dicer.prototype.emit = function(ev) {
|
||||||
|
if (ev === 'finish' && !this._realFinish) {
|
||||||
|
if (!this._finished) {
|
||||||
|
var self = this;
|
||||||
|
process.nextTick(function() {
|
||||||
|
self.emit('error', new Error('Unexpected end of multipart data'));
|
||||||
|
if (self._part && !self._ignoreData) {
|
||||||
|
var type = (self._isPreamble ? 'Preamble' : 'Part');
|
||||||
|
self._part.emit('error', new Error(type + ' terminated early due to unexpected end of multipart data'));
|
||||||
|
self._part.push(null);
|
||||||
|
process.nextTick(function() {
|
||||||
|
self._realFinish = true;
|
||||||
|
self.emit('finish');
|
||||||
|
self._realFinish = false;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self._realFinish = true;
|
||||||
|
self.emit('finish');
|
||||||
|
self._realFinish = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
WritableStream.prototype.emit.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
Dicer.prototype._write = function(data, encoding, cb) {
|
||||||
|
// ignore unexpected data (e.g. extra trailer data after finished)
|
||||||
|
if (!this._hparser && !this._bparser)
|
||||||
|
return cb();
|
||||||
|
|
||||||
|
if (this._headerFirst && this._isPreamble) {
|
||||||
|
if (!this._part) {
|
||||||
|
this._part = new PartStream(this._partOpts);
|
||||||
|
if (this._events.preamble)
|
||||||
|
this.emit('preamble', this._part);
|
||||||
|
else
|
||||||
|
this._ignore();
|
||||||
|
}
|
||||||
|
var r = this._hparser.push(data);
|
||||||
|
if (!this._inHeader && r !== undefined && r < data.length)
|
||||||
|
data = data.slice(r);
|
||||||
|
else
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
// allows for "easier" testing
|
||||||
|
if (this._firstWrite) {
|
||||||
|
this._bparser.push(B_CRLF);
|
||||||
|
this._firstWrite = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._bparser.push(data);
|
||||||
|
|
||||||
|
if (this._pause)
|
||||||
|
this._cb = cb;
|
||||||
|
else
|
||||||
|
cb();
|
||||||
|
};
|
||||||
|
|
||||||
|
Dicer.prototype.reset = function() {
|
||||||
|
this._part = undefined;
|
||||||
|
this._bparser = undefined;
|
||||||
|
this._hparser = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
Dicer.prototype.setBoundary = function(boundary) {
|
||||||
|
var self = this;
|
||||||
|
this._bparser = new StreamSearch('\r\n--' + boundary);
|
||||||
|
this._bparser.on('info', function(isMatch, data, start, end) {
|
||||||
|
self._oninfo(isMatch, data, start, end);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Dicer.prototype._ignore = function() {
|
||||||
|
if (this._part && !this._ignoreData) {
|
||||||
|
this._ignoreData = true;
|
||||||
|
this._part.on('error', EMPTY_FN);
|
||||||
|
// we must perform some kind of read on the stream even though we are
|
||||||
|
// ignoring the data, otherwise node's Readable stream will not emit 'end'
|
||||||
|
// after pushing null to the stream
|
||||||
|
this._part.resume();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Dicer.prototype._oninfo = function(isMatch, data, start, end) {
|
||||||
|
var buf, self = this, i = 0, r, ev, shouldWriteMore = true;
|
||||||
|
|
||||||
|
if (!this._part && this._justMatched && data) {
|
||||||
|
while (this._dashes < 2 && (start + i) < end) {
|
||||||
|
if (data[start + i] === DASH) {
|
||||||
|
++i;
|
||||||
|
++this._dashes;
|
||||||
|
} else {
|
||||||
|
if (this._dashes)
|
||||||
|
buf = B_ONEDASH;
|
||||||
|
this._dashes = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this._dashes === 2) {
|
||||||
|
if ((start + i) < end && this._events.trailer)
|
||||||
|
this.emit('trailer', data.slice(start + i, end));
|
||||||
|
this.reset();
|
||||||
|
this._finished = true;
|
||||||
|
// no more parts will be added
|
||||||
|
if (self._parts === 0) {
|
||||||
|
self._realFinish = true;
|
||||||
|
self.emit('finish');
|
||||||
|
self._realFinish = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this._dashes)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this._justMatched)
|
||||||
|
this._justMatched = false;
|
||||||
|
if (!this._part) {
|
||||||
|
this._part = new PartStream(this._partOpts);
|
||||||
|
this._part._read = function(n) {
|
||||||
|
self._unpause();
|
||||||
|
};
|
||||||
|
ev = this._isPreamble ? 'preamble' : 'part';
|
||||||
|
if (this._events[ev])
|
||||||
|
this.emit(ev, this._part);
|
||||||
|
else
|
||||||
|
this._ignore();
|
||||||
|
if (!this._isPreamble)
|
||||||
|
this._inHeader = true;
|
||||||
|
}
|
||||||
|
if (data && start < end && !this._ignoreData) {
|
||||||
|
if (this._isPreamble || !this._inHeader) {
|
||||||
|
if (buf)
|
||||||
|
shouldWriteMore = this._part.push(buf);
|
||||||
|
shouldWriteMore = this._part.push(data.slice(start, end));
|
||||||
|
if (!shouldWriteMore)
|
||||||
|
this._pause = true;
|
||||||
|
} else if (!this._isPreamble && this._inHeader) {
|
||||||
|
if (buf)
|
||||||
|
this._hparser.push(buf);
|
||||||
|
r = this._hparser.push(data.slice(start, end));
|
||||||
|
if (!this._inHeader && r !== undefined && r < end)
|
||||||
|
this._oninfo(false, data, start + r, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isMatch) {
|
||||||
|
this._hparser.reset();
|
||||||
|
if (this._isPreamble)
|
||||||
|
this._isPreamble = false;
|
||||||
|
else {
|
||||||
|
++this._parts;
|
||||||
|
this._part.on('end', function() {
|
||||||
|
if (--self._parts === 0) {
|
||||||
|
if (self._finished) {
|
||||||
|
self._realFinish = true;
|
||||||
|
self.emit('finish');
|
||||||
|
self._realFinish = false;
|
||||||
|
} else {
|
||||||
|
self._unpause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this._part.push(null);
|
||||||
|
this._part = undefined;
|
||||||
|
this._ignoreData = false;
|
||||||
|
this._justMatched = true;
|
||||||
|
this._dashes = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Dicer.prototype._unpause = function() {
|
||||||
|
if (!this._pause)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._pause = false;
|
||||||
|
if (this._cb) {
|
||||||
|
var cb = this._cb;
|
||||||
|
this._cb = undefined;
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Dicer;
|
110
server/node_modules/dicer/lib/HeaderParser.js
generated
vendored
Normal file
110
server/node_modules/dicer/lib/HeaderParser.js
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
var EventEmitter = require('events').EventEmitter,
|
||||||
|
inherits = require('util').inherits;
|
||||||
|
|
||||||
|
var StreamSearch = require('streamsearch');
|
||||||
|
|
||||||
|
var B_DCRLF = Buffer.from('\r\n\r\n'),
|
||||||
|
RE_CRLF = /\r\n/g,
|
||||||
|
RE_HDR = /^([^:]+):[ \t]?([\x00-\xFF]+)?$/,
|
||||||
|
MAX_HEADER_PAIRS = 2000, // from node's http.js
|
||||||
|
MAX_HEADER_SIZE = 80 * 1024; // from node's http_parser
|
||||||
|
|
||||||
|
function HeaderParser(cfg) {
|
||||||
|
EventEmitter.call(this);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.nread = 0;
|
||||||
|
this.maxed = false;
|
||||||
|
this.npairs = 0;
|
||||||
|
this.maxHeaderPairs = (cfg && typeof cfg.maxHeaderPairs === 'number'
|
||||||
|
? cfg.maxHeaderPairs
|
||||||
|
: MAX_HEADER_PAIRS);
|
||||||
|
this.buffer = '';
|
||||||
|
this.header = {};
|
||||||
|
this.finished = false;
|
||||||
|
this.ss = new StreamSearch(B_DCRLF);
|
||||||
|
this.ss.on('info', function(isMatch, data, start, end) {
|
||||||
|
if (data && !self.maxed) {
|
||||||
|
if (self.nread + (end - start) > MAX_HEADER_SIZE) {
|
||||||
|
end = (MAX_HEADER_SIZE - self.nread);
|
||||||
|
self.nread = MAX_HEADER_SIZE;
|
||||||
|
} else
|
||||||
|
self.nread += (end - start);
|
||||||
|
|
||||||
|
if (self.nread === MAX_HEADER_SIZE)
|
||||||
|
self.maxed = true;
|
||||||
|
|
||||||
|
self.buffer += data.toString('binary', start, end);
|
||||||
|
}
|
||||||
|
if (isMatch)
|
||||||
|
self._finish();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
inherits(HeaderParser, EventEmitter);
|
||||||
|
|
||||||
|
HeaderParser.prototype.push = function(data) {
|
||||||
|
var r = this.ss.push(data);
|
||||||
|
if (this.finished)
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
|
HeaderParser.prototype.reset = function() {
|
||||||
|
this.finished = false;
|
||||||
|
this.buffer = '';
|
||||||
|
this.header = {};
|
||||||
|
this.ss.reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
HeaderParser.prototype._finish = function() {
|
||||||
|
if (this.buffer)
|
||||||
|
this._parseHeader();
|
||||||
|
this.ss.matches = this.ss.maxMatches;
|
||||||
|
var header = this.header;
|
||||||
|
this.header = {};
|
||||||
|
this.buffer = '';
|
||||||
|
this.finished = true;
|
||||||
|
this.nread = this.npairs = 0;
|
||||||
|
this.maxed = false;
|
||||||
|
this.emit('header', header);
|
||||||
|
};
|
||||||
|
|
||||||
|
HeaderParser.prototype._parseHeader = function() {
|
||||||
|
if (this.npairs === this.maxHeaderPairs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var lines = this.buffer.split(RE_CRLF), len = lines.length, m, h,
|
||||||
|
modded = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
if (lines[i].length === 0)
|
||||||
|
continue;
|
||||||
|
if (lines[i][0] === '\t' || lines[i][0] === ' ') {
|
||||||
|
// folded header content
|
||||||
|
// RFC2822 says to just remove the CRLF and not the whitespace following
|
||||||
|
// it, so we follow the RFC and include the leading whitespace ...
|
||||||
|
this.header[h][this.header[h].length - 1] += lines[i];
|
||||||
|
} else {
|
||||||
|
m = RE_HDR.exec(lines[i]);
|
||||||
|
if (m) {
|
||||||
|
h = m[1].toLowerCase();
|
||||||
|
if (m[2]) {
|
||||||
|
if (this.header[h] === undefined)
|
||||||
|
this.header[h] = [m[2]];
|
||||||
|
else
|
||||||
|
this.header[h].push(m[2]);
|
||||||
|
} else
|
||||||
|
this.header[h] = [''];
|
||||||
|
if (++this.npairs === this.maxHeaderPairs)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
this.buffer = lines[i];
|
||||||
|
modded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!modded)
|
||||||
|
this.buffer = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = HeaderParser;
|
11
server/node_modules/dicer/lib/PartStream.js
generated
vendored
Normal file
11
server/node_modules/dicer/lib/PartStream.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
var inherits = require('util').inherits,
|
||||||
|
ReadableStream = require('stream').Readable;
|
||||||
|
|
||||||
|
function PartStream(opts) {
|
||||||
|
ReadableStream.call(this, opts);
|
||||||
|
}
|
||||||
|
inherits(PartStream, ReadableStream);
|
||||||
|
|
||||||
|
PartStream.prototype._read = function(n) {};
|
||||||
|
|
||||||
|
module.exports = PartStream;
|
66
server/node_modules/dicer/package.json
generated
vendored
Normal file
66
server/node_modules/dicer/package.json
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"_from": "dicer@0.3.0",
|
||||||
|
"_id": "dicer@0.3.0",
|
||||||
|
"_inBundle": false,
|
||||||
|
"_integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==",
|
||||||
|
"_location": "/dicer",
|
||||||
|
"_phantomChildren": {},
|
||||||
|
"_requested": {
|
||||||
|
"type": "version",
|
||||||
|
"registry": true,
|
||||||
|
"raw": "dicer@0.3.0",
|
||||||
|
"name": "dicer",
|
||||||
|
"escapedName": "dicer",
|
||||||
|
"rawSpec": "0.3.0",
|
||||||
|
"saveSpec": null,
|
||||||
|
"fetchSpec": "0.3.0"
|
||||||
|
},
|
||||||
|
"_requiredBy": [
|
||||||
|
"/busboy"
|
||||||
|
],
|
||||||
|
"_resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
|
||||||
|
"_shasum": "eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872",
|
||||||
|
"_spec": "dicer@0.3.0",
|
||||||
|
"_where": "/home/sigonasr2/divar/server/node_modules/busboy",
|
||||||
|
"author": {
|
||||||
|
"name": "Brian White",
|
||||||
|
"email": "mscdex@mscdex.net"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/mscdex/dicer/issues"
|
||||||
|
},
|
||||||
|
"bundleDependencies": false,
|
||||||
|
"dependencies": {
|
||||||
|
"streamsearch": "0.1.2"
|
||||||
|
},
|
||||||
|
"deprecated": false,
|
||||||
|
"description": "A very fast streaming multipart parser for node.js",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.5.0"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/mscdex/dicer#readme",
|
||||||
|
"keywords": [
|
||||||
|
"parser",
|
||||||
|
"parse",
|
||||||
|
"parsing",
|
||||||
|
"multipart",
|
||||||
|
"form-data",
|
||||||
|
"streaming"
|
||||||
|
],
|
||||||
|
"licenses": [
|
||||||
|
{
|
||||||
|
"type": "MIT",
|
||||||
|
"url": "http://github.com/mscdex/dicer/raw/master/LICENSE"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"main": "./lib/Dicer",
|
||||||
|
"name": "dicer",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+ssh://git@github.com/mscdex/dicer.git"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": "node test/test.js"
|
||||||
|
},
|
||||||
|
"version": "0.3.0"
|
||||||
|
}
|
31
server/node_modules/dicer/test/fixtures/many-noend/original
generated
vendored
Normal file
31
server/node_modules/dicer/test/fixtures/many-noend/original
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="_method"
|
||||||
|
|
||||||
|
put
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[blog]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[public_email]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[interests]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[bio]"
|
||||||
|
|
||||||
|
hello
|
||||||
|
|
||||||
|
"quote"
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="commit"
|
||||||
|
|
||||||
|
Save
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="media"; filename=""
|
||||||
|
Content-Type: application/octet-stream
|
||||||
|
|
||||||
|
|
1
server/node_modules/dicer/test/fixtures/many-noend/part1
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part1
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
put
|
1
server/node_modules/dicer/test/fixtures/many-noend/part1.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part1.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"_method\""]}
|
0
server/node_modules/dicer/test/fixtures/many-noend/part2
generated
vendored
Normal file
0
server/node_modules/dicer/test/fixtures/many-noend/part2
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part2.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part2.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"profile[blog]\""]}
|
0
server/node_modules/dicer/test/fixtures/many-noend/part3
generated
vendored
Normal file
0
server/node_modules/dicer/test/fixtures/many-noend/part3
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part3.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part3.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"profile[public_email]\""]}
|
0
server/node_modules/dicer/test/fixtures/many-noend/part4
generated
vendored
Normal file
0
server/node_modules/dicer/test/fixtures/many-noend/part4
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part4.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part4.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"profile[interests]\""]}
|
3
server/node_modules/dicer/test/fixtures/many-noend/part5
generated
vendored
Normal file
3
server/node_modules/dicer/test/fixtures/many-noend/part5
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
hello
|
||||||
|
|
||||||
|
"quote"
|
1
server/node_modules/dicer/test/fixtures/many-noend/part5.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part5.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"profile[bio]\""]}
|
1
server/node_modules/dicer/test/fixtures/many-noend/part6
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part6
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Save
|
1
server/node_modules/dicer/test/fixtures/many-noend/part6.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-noend/part6.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"commit\""]}
|
2
server/node_modules/dicer/test/fixtures/many-noend/part7.header
generated
vendored
Normal file
2
server/node_modules/dicer/test/fixtures/many-noend/part7.header
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"media\"; filename=\"\""],
|
||||||
|
"content-type": ["application/octet-stream"]}
|
32
server/node_modules/dicer/test/fixtures/many-wrongboundary/original
generated
vendored
Normal file
32
server/node_modules/dicer/test/fixtures/many-wrongboundary/original
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="_method"
|
||||||
|
|
||||||
|
put
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[blog]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[public_email]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[interests]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[bio]"
|
||||||
|
|
||||||
|
hello
|
||||||
|
|
||||||
|
"quote"
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="media"; filename=""
|
||||||
|
Content-Type: application/octet-stream
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="commit"
|
||||||
|
|
||||||
|
Save
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR--
|
33
server/node_modules/dicer/test/fixtures/many-wrongboundary/preamble
generated
vendored
Normal file
33
server/node_modules/dicer/test/fixtures/many-wrongboundary/preamble
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="_method"
|
||||||
|
|
||||||
|
put
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[blog]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[public_email]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[interests]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[bio]"
|
||||||
|
|
||||||
|
hello
|
||||||
|
|
||||||
|
"quote"
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="media"; filename=""
|
||||||
|
Content-Type: application/octet-stream
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="commit"
|
||||||
|
|
||||||
|
Save
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR--
|
1
server/node_modules/dicer/test/fixtures/many-wrongboundary/preamble.error
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many-wrongboundary/preamble.error
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Preamble terminated early due to unexpected end of multipart data
|
32
server/node_modules/dicer/test/fixtures/many/original
generated
vendored
Normal file
32
server/node_modules/dicer/test/fixtures/many/original
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="_method"
|
||||||
|
|
||||||
|
put
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[blog]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[public_email]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[interests]"
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="profile[bio]"
|
||||||
|
|
||||||
|
hello
|
||||||
|
|
||||||
|
"quote"
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="media"; filename=""
|
||||||
|
Content-Type: application/octet-stream
|
||||||
|
|
||||||
|
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR
|
||||||
|
Content-Disposition: form-data; name="commit"
|
||||||
|
|
||||||
|
Save
|
||||||
|
------WebKitFormBoundaryWLHCs9qmcJJoyjKR--
|
1
server/node_modules/dicer/test/fixtures/many/part1
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part1
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
put
|
1
server/node_modules/dicer/test/fixtures/many/part1.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part1.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"_method\""]}
|
0
server/node_modules/dicer/test/fixtures/many/part2
generated
vendored
Normal file
0
server/node_modules/dicer/test/fixtures/many/part2
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part2.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part2.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"profile[blog]\""]}
|
0
server/node_modules/dicer/test/fixtures/many/part3
generated
vendored
Normal file
0
server/node_modules/dicer/test/fixtures/many/part3
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part3.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part3.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"profile[public_email]\""]}
|
0
server/node_modules/dicer/test/fixtures/many/part4
generated
vendored
Normal file
0
server/node_modules/dicer/test/fixtures/many/part4
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part4.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part4.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"profile[interests]\""]}
|
3
server/node_modules/dicer/test/fixtures/many/part5
generated
vendored
Normal file
3
server/node_modules/dicer/test/fixtures/many/part5
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
hello
|
||||||
|
|
||||||
|
"quote"
|
1
server/node_modules/dicer/test/fixtures/many/part5.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part5.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"profile[bio]\""]}
|
0
server/node_modules/dicer/test/fixtures/many/part6
generated
vendored
Normal file
0
server/node_modules/dicer/test/fixtures/many/part6
generated
vendored
Normal file
2
server/node_modules/dicer/test/fixtures/many/part6.header
generated
vendored
Normal file
2
server/node_modules/dicer/test/fixtures/many/part6.header
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"media\"; filename=\"\""],
|
||||||
|
"content-type": ["application/octet-stream"]}
|
1
server/node_modules/dicer/test/fixtures/many/part7
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part7
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Save
|
1
server/node_modules/dicer/test/fixtures/many/part7.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/many/part7.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"commit\""]}
|
24
server/node_modules/dicer/test/fixtures/nested-full/original
generated
vendored
Normal file
24
server/node_modules/dicer/test/fixtures/nested-full/original
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
User-Agent: foo bar baz
|
||||||
|
Content-Type: multipart/form-data; boundary=AaB03x
|
||||||
|
|
||||||
|
--AaB03x
|
||||||
|
Content-Disposition: form-data; name="foo"
|
||||||
|
|
||||||
|
bar
|
||||||
|
--AaB03x
|
||||||
|
Content-Disposition: form-data; name="files"
|
||||||
|
Content-Type: multipart/mixed, boundary=BbC04y
|
||||||
|
|
||||||
|
--BbC04y
|
||||||
|
Content-Disposition: attachment; filename="file.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
contents
|
||||||
|
--BbC04y
|
||||||
|
Content-Disposition: attachment; filename="flowers.jpg"
|
||||||
|
Content-Type: image/jpeg
|
||||||
|
Content-Transfer-Encoding: binary
|
||||||
|
|
||||||
|
contents
|
||||||
|
--BbC04y--
|
||||||
|
--AaB03x--
|
1
server/node_modules/dicer/test/fixtures/nested-full/part1
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/nested-full/part1
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
bar
|
1
server/node_modules/dicer/test/fixtures/nested-full/part1.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/nested-full/part1.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"foo\""]}
|
12
server/node_modules/dicer/test/fixtures/nested-full/part2
generated
vendored
Normal file
12
server/node_modules/dicer/test/fixtures/nested-full/part2
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
--BbC04y
|
||||||
|
Content-Disposition: attachment; filename="file.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
contents
|
||||||
|
--BbC04y
|
||||||
|
Content-Disposition: attachment; filename="flowers.jpg"
|
||||||
|
Content-Type: image/jpeg
|
||||||
|
Content-Transfer-Encoding: binary
|
||||||
|
|
||||||
|
contents
|
||||||
|
--BbC04y--
|
2
server/node_modules/dicer/test/fixtures/nested-full/part2.header
generated
vendored
Normal file
2
server/node_modules/dicer/test/fixtures/nested-full/part2.header
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"files\""],
|
||||||
|
"content-type": ["multipart/mixed, boundary=BbC04y"]}
|
2
server/node_modules/dicer/test/fixtures/nested-full/preamble.header
generated
vendored
Normal file
2
server/node_modules/dicer/test/fixtures/nested-full/preamble.header
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{"user-agent": ["foo bar baz"],
|
||||||
|
"content-type": ["multipart/form-data; boundary=AaB03x"]}
|
21
server/node_modules/dicer/test/fixtures/nested/original
generated
vendored
Normal file
21
server/node_modules/dicer/test/fixtures/nested/original
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
--AaB03x
|
||||||
|
Content-Disposition: form-data; name="foo"
|
||||||
|
|
||||||
|
bar
|
||||||
|
--AaB03x
|
||||||
|
Content-Disposition: form-data; name="files"
|
||||||
|
Content-Type: multipart/mixed, boundary=BbC04y
|
||||||
|
|
||||||
|
--BbC04y
|
||||||
|
Content-Disposition: attachment; filename="file.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
contents
|
||||||
|
--BbC04y
|
||||||
|
Content-Disposition: attachment; filename="flowers.jpg"
|
||||||
|
Content-Type: image/jpeg
|
||||||
|
Content-Transfer-Encoding: binary
|
||||||
|
|
||||||
|
contents
|
||||||
|
--BbC04y--
|
||||||
|
--AaB03x--
|
1
server/node_modules/dicer/test/fixtures/nested/part1
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/nested/part1
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
bar
|
1
server/node_modules/dicer/test/fixtures/nested/part1.header
generated
vendored
Normal file
1
server/node_modules/dicer/test/fixtures/nested/part1.header
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"foo\""]}
|
12
server/node_modules/dicer/test/fixtures/nested/part2
generated
vendored
Normal file
12
server/node_modules/dicer/test/fixtures/nested/part2
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
--BbC04y
|
||||||
|
Content-Disposition: attachment; filename="file.txt"
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
||||||
|
contents
|
||||||
|
--BbC04y
|
||||||
|
Content-Disposition: attachment; filename="flowers.jpg"
|
||||||
|
Content-Type: image/jpeg
|
||||||
|
Content-Transfer-Encoding: binary
|
||||||
|
|
||||||
|
contents
|
||||||
|
--BbC04y--
|
2
server/node_modules/dicer/test/fixtures/nested/part2.header
generated
vendored
Normal file
2
server/node_modules/dicer/test/fixtures/nested/part2.header
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{"content-disposition": ["form-data; name=\"files\""],
|
||||||
|
"content-type": ["multipart/mixed, boundary=BbC04y"]}
|
87
server/node_modules/dicer/test/test-endfinish.js
generated
vendored
Normal file
87
server/node_modules/dicer/test/test-endfinish.js
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
var Dicer = require('..');
|
||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
var CRLF = '\r\n';
|
||||||
|
var boundary = 'boundary';
|
||||||
|
|
||||||
|
var writeSep = '--' + boundary;
|
||||||
|
|
||||||
|
var writePart = [
|
||||||
|
writeSep,
|
||||||
|
'Content-Type: text/plain',
|
||||||
|
'Content-Length: 0'
|
||||||
|
].join(CRLF)
|
||||||
|
+ CRLF + CRLF
|
||||||
|
+ 'some data' + CRLF;
|
||||||
|
|
||||||
|
var writeEnd = '--' + CRLF;
|
||||||
|
|
||||||
|
var firedEnd = false;
|
||||||
|
var firedFinish = false;
|
||||||
|
|
||||||
|
var dicer = new Dicer({boundary: boundary});
|
||||||
|
dicer.on('part', partListener);
|
||||||
|
dicer.on('finish', finishListener);
|
||||||
|
dicer.write(writePart+writeSep);
|
||||||
|
|
||||||
|
function partListener(partReadStream) {
|
||||||
|
partReadStream.on('data', function(){});
|
||||||
|
partReadStream.on('end', partEndListener);
|
||||||
|
}
|
||||||
|
function partEndListener() {
|
||||||
|
firedEnd = true;
|
||||||
|
setImmediate(afterEnd);
|
||||||
|
}
|
||||||
|
function afterEnd() {
|
||||||
|
dicer.end(writeEnd);
|
||||||
|
setImmediate(afterWrite);
|
||||||
|
}
|
||||||
|
function finishListener() {
|
||||||
|
assert(firedEnd, 'Failed to end before finishing');
|
||||||
|
firedFinish = true;
|
||||||
|
test2();
|
||||||
|
}
|
||||||
|
function afterWrite() {
|
||||||
|
assert(firedFinish, 'Failed to finish');
|
||||||
|
}
|
||||||
|
|
||||||
|
var isPausePush = true;
|
||||||
|
|
||||||
|
var firedPauseCallback = false;
|
||||||
|
var firedPauseFinish = false;
|
||||||
|
|
||||||
|
var dicer2 = null;
|
||||||
|
|
||||||
|
function test2() {
|
||||||
|
dicer2 = new Dicer({boundary: boundary});
|
||||||
|
dicer2.on('part', pausePartListener);
|
||||||
|
dicer2.on('finish', pauseFinish);
|
||||||
|
dicer2.write(writePart+writeSep, 'utf8', pausePartCallback);
|
||||||
|
setImmediate(pauseAfterWrite);
|
||||||
|
}
|
||||||
|
function pausePartListener(partReadStream) {
|
||||||
|
partReadStream.on('data', function(){});
|
||||||
|
partReadStream.on('end', function(){});
|
||||||
|
var realPush = partReadStream.push;
|
||||||
|
partReadStream.push = function fakePush() {
|
||||||
|
realPush.apply(partReadStream, arguments);
|
||||||
|
if (!isPausePush)
|
||||||
|
return true;
|
||||||
|
isPausePush = false;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function pauseAfterWrite() {
|
||||||
|
dicer2.end(writeEnd);
|
||||||
|
setImmediate(pauseAfterEnd);
|
||||||
|
}
|
||||||
|
function pauseAfterEnd() {
|
||||||
|
assert(firedPauseCallback, 'Failed to call callback after pause');
|
||||||
|
assert(firedPauseFinish, 'Failed to finish after pause');
|
||||||
|
}
|
||||||
|
function pauseFinish() {
|
||||||
|
firedPauseFinish = true;
|
||||||
|
}
|
||||||
|
function pausePartCallback() {
|
||||||
|
firedPauseCallback = true;
|
||||||
|
}
|
68
server/node_modules/dicer/test/test-headerparser.js
generated
vendored
Normal file
68
server/node_modules/dicer/test/test-headerparser.js
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
var assert = require('assert'),
|
||||||
|
path = require('path');
|
||||||
|
|
||||||
|
var HeaderParser = require('../lib/HeaderParser');
|
||||||
|
|
||||||
|
var DCRLF = '\r\n\r\n',
|
||||||
|
MAXED_BUFFER = Buffer.allocUnsafe(128 * 1024);
|
||||||
|
MAXED_BUFFER.fill(0x41); // 'A'
|
||||||
|
|
||||||
|
var group = path.basename(__filename, '.js') + '/';
|
||||||
|
|
||||||
|
[
|
||||||
|
{ source: DCRLF,
|
||||||
|
expected: {},
|
||||||
|
what: 'No header'
|
||||||
|
},
|
||||||
|
{ source: ['Content-Type:\t text/plain',
|
||||||
|
'Content-Length:0'
|
||||||
|
].join('\r\n') + DCRLF,
|
||||||
|
expected: {'content-type': [' text/plain'], 'content-length': ['0']},
|
||||||
|
what: 'Value spacing'
|
||||||
|
},
|
||||||
|
{ source: ['Content-Type:\r\n text/plain',
|
||||||
|
'Foo:\r\n bar\r\n baz',
|
||||||
|
].join('\r\n') + DCRLF,
|
||||||
|
expected: {'content-type': [' text/plain'], 'foo': [' bar baz']},
|
||||||
|
what: 'Folded values'
|
||||||
|
},
|
||||||
|
{ source: ['Content-Type:',
|
||||||
|
'Foo: ',
|
||||||
|
].join('\r\n') + DCRLF,
|
||||||
|
expected: {'content-type': [''], 'foo': ['']},
|
||||||
|
what: 'Empty values'
|
||||||
|
},
|
||||||
|
{ source: MAXED_BUFFER.toString('ascii') + DCRLF,
|
||||||
|
expected: {},
|
||||||
|
what: 'Max header size (single chunk)'
|
||||||
|
},
|
||||||
|
{ source: ['ABCDEFGHIJ', MAXED_BUFFER.toString('ascii'), DCRLF],
|
||||||
|
expected: {},
|
||||||
|
what: 'Max header size (multiple chunks #1)'
|
||||||
|
},
|
||||||
|
{ source: [MAXED_BUFFER.toString('ascii'), MAXED_BUFFER.toString('ascii'), DCRLF],
|
||||||
|
expected: {},
|
||||||
|
what: 'Max header size (multiple chunk #2)'
|
||||||
|
},
|
||||||
|
].forEach(function(v) {
|
||||||
|
var parser = new HeaderParser(),
|
||||||
|
fired = false;
|
||||||
|
|
||||||
|
parser.on('header', function(header) {
|
||||||
|
assert(!fired, makeMsg(v.what, 'Header event fired more than once'));
|
||||||
|
fired = true;
|
||||||
|
assert.deepEqual(header,
|
||||||
|
v.expected,
|
||||||
|
makeMsg(v.what, 'Parsed result mismatch'));
|
||||||
|
});
|
||||||
|
if (!Array.isArray(v.source))
|
||||||
|
v.source = [v.source];
|
||||||
|
v.source.forEach(function(s) {
|
||||||
|
parser.push(s);
|
||||||
|
});
|
||||||
|
assert(fired, makeMsg(v.what, 'Did not receive header from parser'));
|
||||||
|
});
|
||||||
|
|
||||||
|
function makeMsg(what, msg) {
|
||||||
|
return '[' + group + what + ']: ' + msg;
|
||||||
|
}
|
148
server/node_modules/dicer/test/test-multipart-extra-trailer.js
generated
vendored
Normal file
148
server/node_modules/dicer/test/test-multipart-extra-trailer.js
generated
vendored
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
var Dicer = require('..');
|
||||||
|
var assert = require('assert'),
|
||||||
|
fs = require('fs'),
|
||||||
|
path = require('path'),
|
||||||
|
inspect = require('util').inspect;
|
||||||
|
|
||||||
|
var FIXTURES_ROOT = __dirname + '/fixtures/';
|
||||||
|
|
||||||
|
var t = 0,
|
||||||
|
group = path.basename(__filename, '.js') + '/';
|
||||||
|
|
||||||
|
var tests = [
|
||||||
|
{ source: 'many',
|
||||||
|
opts: { boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' },
|
||||||
|
chsize: 16,
|
||||||
|
nparts: 7,
|
||||||
|
what: 'Extra trailer data pushed after finished'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (t === tests.length)
|
||||||
|
return;
|
||||||
|
var v = tests[t],
|
||||||
|
fixtureBase = FIXTURES_ROOT + v.source,
|
||||||
|
fd,
|
||||||
|
n = 0,
|
||||||
|
buffer = Buffer.allocUnsafe(v.chsize),
|
||||||
|
state = { parts: [] };
|
||||||
|
|
||||||
|
fd = fs.openSync(fixtureBase + '/original', 'r');
|
||||||
|
|
||||||
|
var dicer = new Dicer(v.opts),
|
||||||
|
error,
|
||||||
|
partErrors = 0,
|
||||||
|
finishes = 0;
|
||||||
|
|
||||||
|
dicer.on('part', function(p) {
|
||||||
|
var part = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: undefined,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
p.on('header', function(h) {
|
||||||
|
part.header = h;
|
||||||
|
}).on('data', function(data) {
|
||||||
|
// make a copy because we are using readSync which re-uses a buffer ...
|
||||||
|
var copy = Buffer.allocUnsafe(data.length);
|
||||||
|
data.copy(copy);
|
||||||
|
data = copy;
|
||||||
|
if (!part.body)
|
||||||
|
part.body = [ data ];
|
||||||
|
else
|
||||||
|
part.body.push(data);
|
||||||
|
part.bodylen += data.length;
|
||||||
|
}).on('error', function(err) {
|
||||||
|
part.error = err;
|
||||||
|
++partErrors;
|
||||||
|
}).on('end', function() {
|
||||||
|
if (part.body)
|
||||||
|
part.body = Buffer.concat(part.body, part.bodylen);
|
||||||
|
state.parts.push(part);
|
||||||
|
});
|
||||||
|
}).on('error', function(err) {
|
||||||
|
error = err;
|
||||||
|
}).on('finish', function() {
|
||||||
|
assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
|
||||||
|
|
||||||
|
if (v.dicerError)
|
||||||
|
assert(error !== undefined, makeMsg(v.what, 'Expected error'));
|
||||||
|
else
|
||||||
|
assert(error === undefined, makeMsg(v.what, 'Unexpected error'));
|
||||||
|
|
||||||
|
if (v.events && v.events.indexOf('part') > -1) {
|
||||||
|
assert.equal(state.parts.length,
|
||||||
|
v.nparts,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part count mismatch:\nActual: '
|
||||||
|
+ state.parts.length
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ v.nparts));
|
||||||
|
|
||||||
|
if (!v.npartErrors)
|
||||||
|
v.npartErrors = 0;
|
||||||
|
assert.equal(partErrors,
|
||||||
|
v.npartErrors,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part errors mismatch:\nActual: '
|
||||||
|
+ partErrors
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ v.npartErrors));
|
||||||
|
|
||||||
|
for (var i = 0, header, body; i < v.nparts; ++i) {
|
||||||
|
if (fs.existsSync(fixtureBase + '/part' + (i+1))) {
|
||||||
|
body = fs.readFileSync(fixtureBase + '/part' + (i+1));
|
||||||
|
if (body.length === 0)
|
||||||
|
body = undefined;
|
||||||
|
} else
|
||||||
|
body = undefined;
|
||||||
|
assert.deepEqual(state.parts[i].body,
|
||||||
|
body,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part #' + (i+1) + ' body mismatch'));
|
||||||
|
if (fs.existsSync(fixtureBase + '/part' + (i+1) + '.header')) {
|
||||||
|
header = fs.readFileSync(fixtureBase
|
||||||
|
+ '/part' + (i+1) + '.header', 'binary');
|
||||||
|
header = JSON.parse(header);
|
||||||
|
} else
|
||||||
|
header = undefined;
|
||||||
|
assert.deepEqual(state.parts[i].header,
|
||||||
|
header,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part #' + (i+1)
|
||||||
|
+ ' parsed header mismatch:\nActual: '
|
||||||
|
+ inspect(state.parts[i].header)
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ inspect(header)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++t;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
n = fs.readSync(fd, buffer, 0, buffer.length, null);
|
||||||
|
if (n === 0) {
|
||||||
|
setTimeout(function() {
|
||||||
|
dicer.write('\r\n\r\n\r\n');
|
||||||
|
dicer.end();
|
||||||
|
}, 50);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dicer.write(n === buffer.length ? buffer : buffer.slice(0, n));
|
||||||
|
}
|
||||||
|
fs.closeSync(fd);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
|
||||||
|
function makeMsg(what, msg) {
|
||||||
|
return '[' + group + what + ']: ' + msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert(t === tests.length,
|
||||||
|
makeMsg('_exit', 'Only ran ' + t + '/' + tests.length + ' tests'));
|
||||||
|
});
|
228
server/node_modules/dicer/test/test-multipart-nolisteners.js
generated
vendored
Normal file
228
server/node_modules/dicer/test/test-multipart-nolisteners.js
generated
vendored
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
var Dicer = require('..');
|
||||||
|
var assert = require('assert'),
|
||||||
|
fs = require('fs'),
|
||||||
|
path = require('path'),
|
||||||
|
inspect = require('util').inspect;
|
||||||
|
|
||||||
|
var FIXTURES_ROOT = __dirname + '/fixtures/';
|
||||||
|
|
||||||
|
var t = 0,
|
||||||
|
group = path.basename(__filename, '.js') + '/';
|
||||||
|
|
||||||
|
var tests = [
|
||||||
|
{ source: 'many',
|
||||||
|
opts: { boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' },
|
||||||
|
chsize: 16,
|
||||||
|
nparts: 0,
|
||||||
|
what: 'No preamble or part listeners'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (t === tests.length)
|
||||||
|
return;
|
||||||
|
var v = tests[t],
|
||||||
|
fixtureBase = FIXTURES_ROOT + v.source,
|
||||||
|
fd,
|
||||||
|
n = 0,
|
||||||
|
buffer = Buffer.allocUnsafe(v.chsize),
|
||||||
|
state = { done: false, parts: [], preamble: undefined };
|
||||||
|
|
||||||
|
fd = fs.openSync(fixtureBase + '/original', 'r');
|
||||||
|
|
||||||
|
var dicer = new Dicer(v.opts),
|
||||||
|
error,
|
||||||
|
partErrors = 0,
|
||||||
|
finishes = 0;
|
||||||
|
|
||||||
|
if (v.events && v.events.indexOf('preamble') > -1) {
|
||||||
|
dicer.on('preamble', function(p) {
|
||||||
|
var preamble = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: undefined,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
p.on('header', function(h) {
|
||||||
|
preamble.header = h;
|
||||||
|
}).on('data', function(data) {
|
||||||
|
// make a copy because we are using readSync which re-uses a buffer ...
|
||||||
|
var copy = Buffer.allocUnsafe(data.length);
|
||||||
|
data.copy(copy);
|
||||||
|
data = copy;
|
||||||
|
if (!preamble.body)
|
||||||
|
preamble.body = [ data ];
|
||||||
|
else
|
||||||
|
preamble.body.push(data);
|
||||||
|
preamble.bodylen += data.length;
|
||||||
|
}).on('error', function(err) {
|
||||||
|
preamble.error = err;
|
||||||
|
}).on('end', function() {
|
||||||
|
if (preamble.body)
|
||||||
|
preamble.body = Buffer.concat(preamble.body, preamble.bodylen);
|
||||||
|
if (preamble.body || preamble.header)
|
||||||
|
state.preamble = preamble;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (v.events && v.events.indexOf('part') > -1) {
|
||||||
|
dicer.on('part', function(p) {
|
||||||
|
var part = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: undefined,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
p.on('header', function(h) {
|
||||||
|
part.header = h;
|
||||||
|
}).on('data', function(data) {
|
||||||
|
// make a copy because we are using readSync which re-uses a buffer ...
|
||||||
|
var copy = Buffer.allocUnsafe(data.length);
|
||||||
|
data.copy(copy);
|
||||||
|
data = copy;
|
||||||
|
if (!part.body)
|
||||||
|
part.body = [ data ];
|
||||||
|
else
|
||||||
|
part.body.push(data);
|
||||||
|
part.bodylen += data.length;
|
||||||
|
}).on('error', function(err) {
|
||||||
|
part.error = err;
|
||||||
|
++partErrors;
|
||||||
|
}).on('end', function() {
|
||||||
|
if (part.body)
|
||||||
|
part.body = Buffer.concat(part.body, part.bodylen);
|
||||||
|
state.parts.push(part);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dicer.on('error', function(err) {
|
||||||
|
error = err;
|
||||||
|
}).on('finish', function() {
|
||||||
|
assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
|
||||||
|
|
||||||
|
if (v.dicerError)
|
||||||
|
assert(error !== undefined, makeMsg(v.what, 'Expected error'));
|
||||||
|
else
|
||||||
|
assert(error === undefined, makeMsg(v.what, 'Unexpected error'));
|
||||||
|
|
||||||
|
if (v.events && v.events.indexOf('preamble') > -1) {
|
||||||
|
var preamble;
|
||||||
|
if (fs.existsSync(fixtureBase + '/preamble')) {
|
||||||
|
var prebody = fs.readFileSync(fixtureBase + '/preamble');
|
||||||
|
if (prebody.length) {
|
||||||
|
preamble = {
|
||||||
|
body: prebody,
|
||||||
|
bodylen: prebody.length,
|
||||||
|
error: undefined,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fs.existsSync(fixtureBase + '/preamble.header')) {
|
||||||
|
var prehead = JSON.parse(fs.readFileSync(fixtureBase
|
||||||
|
+ '/preamble.header', 'binary'));
|
||||||
|
if (!preamble) {
|
||||||
|
preamble = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: undefined,
|
||||||
|
header: prehead
|
||||||
|
};
|
||||||
|
} else
|
||||||
|
preamble.header = prehead;
|
||||||
|
}
|
||||||
|
if (fs.existsSync(fixtureBase + '/preamble.error')) {
|
||||||
|
var err = new Error(fs.readFileSync(fixtureBase
|
||||||
|
+ '/preamble.error', 'binary'));
|
||||||
|
if (!preamble) {
|
||||||
|
preamble = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: err,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
} else
|
||||||
|
preamble.error = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepEqual(state.preamble,
|
||||||
|
preamble,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Preamble mismatch:\nActual:'
|
||||||
|
+ inspect(state.preamble)
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ inspect(preamble)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v.events && v.events.indexOf('part') > -1) {
|
||||||
|
assert.equal(state.parts.length,
|
||||||
|
v.nparts,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part count mismatch:\nActual: '
|
||||||
|
+ state.parts.length
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ v.nparts));
|
||||||
|
|
||||||
|
if (!v.npartErrors)
|
||||||
|
v.npartErrors = 0;
|
||||||
|
assert.equal(partErrors,
|
||||||
|
v.npartErrors,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part errors mismatch:\nActual: '
|
||||||
|
+ partErrors
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ v.npartErrors));
|
||||||
|
|
||||||
|
for (var i = 0, header, body; i < v.nparts; ++i) {
|
||||||
|
if (fs.existsSync(fixtureBase + '/part' + (i+1))) {
|
||||||
|
body = fs.readFileSync(fixtureBase + '/part' + (i+1));
|
||||||
|
if (body.length === 0)
|
||||||
|
body = undefined;
|
||||||
|
} else
|
||||||
|
body = undefined;
|
||||||
|
assert.deepEqual(state.parts[i].body,
|
||||||
|
body,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part #' + (i+1) + ' body mismatch'));
|
||||||
|
if (fs.existsSync(fixtureBase + '/part' + (i+1) + '.header')) {
|
||||||
|
header = fs.readFileSync(fixtureBase
|
||||||
|
+ '/part' + (i+1) + '.header', 'binary');
|
||||||
|
header = JSON.parse(header);
|
||||||
|
} else
|
||||||
|
header = undefined;
|
||||||
|
assert.deepEqual(state.parts[i].header,
|
||||||
|
header,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part #' + (i+1)
|
||||||
|
+ ' parsed header mismatch:\nActual: '
|
||||||
|
+ inspect(state.parts[i].header)
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ inspect(header)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++t;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
n = fs.readSync(fd, buffer, 0, buffer.length, null);
|
||||||
|
if (n === 0) {
|
||||||
|
dicer.end();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dicer.write(n === buffer.length ? buffer : buffer.slice(0, n));
|
||||||
|
}
|
||||||
|
fs.closeSync(fd);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
|
||||||
|
function makeMsg(what, msg) {
|
||||||
|
return '[' + group + what + ']: ' + msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert(t === tests.length,
|
||||||
|
makeMsg('_exit', 'Only ran ' + t + '/' + tests.length + ' tests'));
|
||||||
|
});
|
240
server/node_modules/dicer/test/test-multipart.js
generated
vendored
Normal file
240
server/node_modules/dicer/test/test-multipart.js
generated
vendored
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
var Dicer = require('..');
|
||||||
|
var assert = require('assert'),
|
||||||
|
fs = require('fs'),
|
||||||
|
path = require('path'),
|
||||||
|
inspect = require('util').inspect;
|
||||||
|
|
||||||
|
var FIXTURES_ROOT = __dirname + '/fixtures/';
|
||||||
|
|
||||||
|
var t = 0,
|
||||||
|
group = path.basename(__filename, '.js') + '/';
|
||||||
|
|
||||||
|
var tests = [
|
||||||
|
{ source: 'nested',
|
||||||
|
opts: { boundary: 'AaB03x' },
|
||||||
|
chsize: 32,
|
||||||
|
nparts: 2,
|
||||||
|
what: 'One nested multipart'
|
||||||
|
},
|
||||||
|
{ source: 'many',
|
||||||
|
opts: { boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' },
|
||||||
|
chsize: 16,
|
||||||
|
nparts: 7,
|
||||||
|
what: 'Many parts'
|
||||||
|
},
|
||||||
|
{ source: 'many-wrongboundary',
|
||||||
|
opts: { boundary: 'LOLOLOL' },
|
||||||
|
chsize: 8,
|
||||||
|
nparts: 0,
|
||||||
|
dicerError: true,
|
||||||
|
what: 'Many parts, wrong boundary'
|
||||||
|
},
|
||||||
|
{ source: 'many-noend',
|
||||||
|
opts: { boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' },
|
||||||
|
chsize: 16,
|
||||||
|
nparts: 7,
|
||||||
|
npartErrors: 1,
|
||||||
|
dicerError: true,
|
||||||
|
what: 'Many parts, end boundary missing, 1 file open'
|
||||||
|
},
|
||||||
|
{ source: 'nested-full',
|
||||||
|
opts: { boundary: 'AaB03x', headerFirst: true },
|
||||||
|
chsize: 32,
|
||||||
|
nparts: 2,
|
||||||
|
what: 'One nested multipart with preceding header'
|
||||||
|
},
|
||||||
|
{ source: 'nested-full',
|
||||||
|
opts: { headerFirst: true },
|
||||||
|
chsize: 32,
|
||||||
|
nparts: 2,
|
||||||
|
setBoundary: 'AaB03x',
|
||||||
|
what: 'One nested multipart with preceding header, using setBoundary'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (t === tests.length)
|
||||||
|
return;
|
||||||
|
var v = tests[t],
|
||||||
|
fixtureBase = FIXTURES_ROOT + v.source,
|
||||||
|
n = 0,
|
||||||
|
buffer = Buffer.allocUnsafe(v.chsize),
|
||||||
|
state = { parts: [], preamble: undefined };
|
||||||
|
|
||||||
|
var dicer = new Dicer(v.opts),
|
||||||
|
error,
|
||||||
|
partErrors = 0,
|
||||||
|
finishes = 0;
|
||||||
|
|
||||||
|
dicer.on('preamble', function(p) {
|
||||||
|
var preamble = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: undefined,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
p.on('header', function(h) {
|
||||||
|
preamble.header = h;
|
||||||
|
if (v.setBoundary)
|
||||||
|
dicer.setBoundary(v.setBoundary);
|
||||||
|
}).on('data', function(data) {
|
||||||
|
// make a copy because we are using readSync which re-uses a buffer ...
|
||||||
|
var copy = Buffer.allocUnsafe(data.length);
|
||||||
|
data.copy(copy);
|
||||||
|
data = copy;
|
||||||
|
if (!preamble.body)
|
||||||
|
preamble.body = [ data ];
|
||||||
|
else
|
||||||
|
preamble.body.push(data);
|
||||||
|
preamble.bodylen += data.length;
|
||||||
|
}).on('error', function(err) {
|
||||||
|
preamble.error = err;
|
||||||
|
}).on('end', function() {
|
||||||
|
if (preamble.body)
|
||||||
|
preamble.body = Buffer.concat(preamble.body, preamble.bodylen);
|
||||||
|
if (preamble.body || preamble.header)
|
||||||
|
state.preamble = preamble;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
dicer.on('part', function(p) {
|
||||||
|
var part = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: undefined,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
p.on('header', function(h) {
|
||||||
|
part.header = h;
|
||||||
|
}).on('data', function(data) {
|
||||||
|
if (!part.body)
|
||||||
|
part.body = [ data ];
|
||||||
|
else
|
||||||
|
part.body.push(data);
|
||||||
|
part.bodylen += data.length;
|
||||||
|
}).on('error', function(err) {
|
||||||
|
part.error = err;
|
||||||
|
++partErrors;
|
||||||
|
}).on('end', function() {
|
||||||
|
if (part.body)
|
||||||
|
part.body = Buffer.concat(part.body, part.bodylen);
|
||||||
|
state.parts.push(part);
|
||||||
|
});
|
||||||
|
}).on('error', function(err) {
|
||||||
|
error = err;
|
||||||
|
}).on('finish', function() {
|
||||||
|
assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
|
||||||
|
|
||||||
|
if (v.dicerError)
|
||||||
|
assert(error !== undefined, makeMsg(v.what, 'Expected error'));
|
||||||
|
else
|
||||||
|
assert(error === undefined, makeMsg(v.what, 'Unexpected error: ' + error));
|
||||||
|
|
||||||
|
var preamble;
|
||||||
|
if (fs.existsSync(fixtureBase + '/preamble')) {
|
||||||
|
var prebody = fs.readFileSync(fixtureBase + '/preamble');
|
||||||
|
if (prebody.length) {
|
||||||
|
preamble = {
|
||||||
|
body: prebody,
|
||||||
|
bodylen: prebody.length,
|
||||||
|
error: undefined,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fs.existsSync(fixtureBase + '/preamble.header')) {
|
||||||
|
var prehead = JSON.parse(fs.readFileSync(fixtureBase
|
||||||
|
+ '/preamble.header', 'binary'));
|
||||||
|
if (!preamble) {
|
||||||
|
preamble = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: undefined,
|
||||||
|
header: prehead
|
||||||
|
};
|
||||||
|
} else
|
||||||
|
preamble.header = prehead;
|
||||||
|
}
|
||||||
|
if (fs.existsSync(fixtureBase + '/preamble.error')) {
|
||||||
|
var err = new Error(fs.readFileSync(fixtureBase
|
||||||
|
+ '/preamble.error', 'binary'));
|
||||||
|
if (!preamble) {
|
||||||
|
preamble = {
|
||||||
|
body: undefined,
|
||||||
|
bodylen: 0,
|
||||||
|
error: err,
|
||||||
|
header: undefined
|
||||||
|
};
|
||||||
|
} else
|
||||||
|
preamble.error = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepEqual(state.preamble,
|
||||||
|
preamble,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Preamble mismatch:\nActual:'
|
||||||
|
+ inspect(state.preamble)
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ inspect(preamble)));
|
||||||
|
|
||||||
|
assert.equal(state.parts.length,
|
||||||
|
v.nparts,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part count mismatch:\nActual: '
|
||||||
|
+ state.parts.length
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ v.nparts));
|
||||||
|
|
||||||
|
if (!v.npartErrors)
|
||||||
|
v.npartErrors = 0;
|
||||||
|
assert.equal(partErrors,
|
||||||
|
v.npartErrors,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part errors mismatch:\nActual: '
|
||||||
|
+ partErrors
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ v.npartErrors));
|
||||||
|
|
||||||
|
for (var i = 0, header, body; i < v.nparts; ++i) {
|
||||||
|
if (fs.existsSync(fixtureBase + '/part' + (i+1))) {
|
||||||
|
body = fs.readFileSync(fixtureBase + '/part' + (i+1));
|
||||||
|
if (body.length === 0)
|
||||||
|
body = undefined;
|
||||||
|
} else
|
||||||
|
body = undefined;
|
||||||
|
assert.deepEqual(state.parts[i].body,
|
||||||
|
body,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part #' + (i+1) + ' body mismatch'));
|
||||||
|
if (fs.existsSync(fixtureBase + '/part' + (i+1) + '.header')) {
|
||||||
|
header = fs.readFileSync(fixtureBase
|
||||||
|
+ '/part' + (i+1) + '.header', 'binary');
|
||||||
|
header = JSON.parse(header);
|
||||||
|
} else
|
||||||
|
header = undefined;
|
||||||
|
assert.deepEqual(state.parts[i].header,
|
||||||
|
header,
|
||||||
|
makeMsg(v.what,
|
||||||
|
'Part #' + (i+1)
|
||||||
|
+ ' parsed header mismatch:\nActual: '
|
||||||
|
+ inspect(state.parts[i].header)
|
||||||
|
+ '\nExpected: '
|
||||||
|
+ inspect(header)));
|
||||||
|
}
|
||||||
|
++t;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.createReadStream(fixtureBase + '/original').pipe(dicer);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
|
||||||
|
function makeMsg(what, msg) {
|
||||||
|
return '[' + group + what + ']: ' + msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert(t === tests.length,
|
||||||
|
makeMsg('_exit', 'Only ran ' + t + '/' + tests.length + ' tests'));
|
||||||
|
});
|
4
server/node_modules/dicer/test/test.js
generated
vendored
Normal file
4
server/node_modules/dicer/test/test.js
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
require('fs').readdirSync(__dirname).forEach(function(f) {
|
||||||
|
if (f.substr(0, 5) === 'test-')
|
||||||
|
require('./' + f);
|
||||||
|
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user