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=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">
|
||||
<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.
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
.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() {
|
||||
return (<Router>
|
||||
<div className="container content">
|
||||
@ -303,6 +332,9 @@ function App() {
|
||||
<Route path="/user/:username">
|
||||
<Profile/>
|
||||
</Route>
|
||||
<Route path="/submitplay">
|
||||
<Submit/>
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<h1 className="title">Project DivaR</h1>
|
||||
Under construction!
|
||||
|
@ -8,6 +8,13 @@ module.exports = function(app) {
|
||||
changeOrigin: true,
|
||||
})
|
||||
);
|
||||
app.use(
|
||||
"/upload",
|
||||
createProxyMiddleware({
|
||||
target: 'http://server:4501',
|
||||
changeOrigin: true,
|
||||
})
|
||||
);
|
||||
app.use(
|
||||
"/song/:songname",
|
||||
createProxyMiddleware({
|
||||
@ -113,4 +120,11 @@ module.exports = function(app) {
|
||||
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() {
|
||||
}
|
||||
|
||||
}
|
3
server/.gitignore
vendored
3
server/.gitignore
vendored
@ -1 +1,2 @@
|
||||
.env.twitter
|
||||
.env.twitter
|
||||
files
|
@ -12,6 +12,12 @@ app.use(
|
||||
extended: true,
|
||||
})
|
||||
)
|
||||
const fileUpload = require('express-fileupload');
|
||||
app.use(
|
||||
fileUpload({createParentPath:true,
|
||||
safeFileNames: true, preserveExtension: true})
|
||||
)
|
||||
|
||||
|
||||
|
||||
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) => {
|
||||
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) {
|
||||
@ -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"))
|
||||
{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])
|
||||
.then((data)=>{if(data && data.rows.length>0){if (data.rows[0].authentication_token===req.body.authentication_token){
|
||||
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)=>{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){
|
||||
songsubmitdata = data.rows[0];
|
||||
//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;
|
||||
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])})
|
||||
@ -315,6 +355,9 @@ function Process(data){
|
||||
}
|
||||
return "Done!";
|
||||
}
|
||||
|
||||
app.use('/files',express.static('files'))
|
||||
|
||||
/*
|
||||
axios.get('https://api.twitter.com/1.1/search/tweets.json?q=@divarbot', {
|
||||
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