Skip to content

Instantly share code, notes, and snippets.

@odeke-em
Created May 13, 2016 03:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odeke-em/46a8deba3ded6bb4f2169e2e80928442 to your computer and use it in GitHub Desktop.
Save odeke-em/46a8deba3ded6bb4f2169e2e80928442 to your computer and use it in GitHub Desktop.
Code to setup reproduction to try to fix https://github.com/golang/go/issues/15664
package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func exitIfErr(err error) {
if err == nil {
return
}
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(-1)
}
func main() {
if len(os.Args) < 2 {
exitIfErr(fmt.Errorf("expecting atleast one arg"))
}
rest := os.Args[1:]
for _, filename := range rest {
f, err := os.Open(filename)
exitIfErr(err)
fields := map[string]string{
"filename": filename,
}
res, err := multipartUpload("http://localhost:8090/validate", f, fields)
_ = f.Close()
exitIfErr(err)
io.Copy(os.Stdout, res.Body)
_ = res.Body.Close()
}
}
func createFormFile(mw *multipart.Writer, filename string) (io.Writer, error) {
return mw.CreateFormFile("file", filename)
}
func multipartUpload(destURL string, f io.Reader, fields map[string]string) (*http.Response, error) {
if f == nil {
return nil, fmt.Errorf("bodySource cannot be nil")
}
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
fw, err := createFormFile(writer, fields["filename"])
if err != nil {
return nil, fmt.Errorf("createFormFile %v", err)
}
n, err := io.Copy(fw, f)
if err != nil && n < 1 {
return nil, fmt.Errorf("copying fileWriter %v", err)
}
for k, v := range fields {
_ = writer.WriteField(k, v)
}
err = writer.Close()
if err != nil {
return nil, fmt.Errorf("writerClose: %v", err)
}
req, err := http.NewRequest("POST", destURL, body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
if req.Close && req.Body != nil {
defer req.Body.Close()
}
return http.DefaultClient.Do(req)
}
package main
import (
"fmt"
"log"
"net/http"
"os/exec"
)
const html = `
<html>
Validation
<form method="POST" action="/validate" enctype="multipart/form-data">
<input type="file" name="file" />
<br />
<input type="submit" value="Send" />
</form>
</html>
`
func validate(w http.ResponseWriter, r *http.Request) {
if err := r.ParseMultipartForm(1 << 20); err != nil {
fmt.Fprintf(w, "parseForm: %v\n", err)
return
}
file, header, err := r.FormFile("file")
if err != nil {
fmt.Fprintf(w, "formFile retrieval %s\n", err)
fmt.Println(err)
return
}
defer file.Close()
fmt.Fprintf(w, "%s\n", header.Header)
fmt.Fprintf(w, "%s\n", header.Filename)
fmt.Println(header.Header)
fmt.Println(header.Filename)
}
func index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, html)
}
func main() {
addr := ":8090"
http.HandleFunc("/", index)
http.HandleFunc("/validate", validate)
if false { // This is your specific command, not present on *NIX
go exec.Command("rundll32", "url.dll,FileProtocolHandler",
fmt.Sprintf("http://localhost%s", addr)).Start()
}
if err := http.ListenAndServe(addr, nil); err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment