Skip to content

Instantly share code, notes, and snippets.

@6ewis 6ewis/multipart.go Secret
Created Sep 20, 2014

Embed
What would you like to do?
multipart http request in Go
package main
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
"net/url"
"os"
"path/filepath"
"runtime"
"time"
)
const (
uri = "http://privateserver.io"
name = "Lewis Dackam"
phone = "416-907-1095"
email = "lewis.dackam@gmail.com"
subject = "'Sending arbitraryfile'"
notes = `Sending arbitraryfile to server including current file`
arbitraryfile = "/arbitraryfile.pdf"
)
func generateSignature() url.Values {
params := url.Values{}
params.Set("name", name)
params.Add("phone", phone)
params.Add("email", email)
params.Add("subject", subject)
params.Add("notes", notes)
formatedTime := time.Now().Format(time.RFC1123)
params.Add("time", formatedTime)
buff := bytes.NewBufferString(params.Encode())
resp, err := http.Post(uri, "application/x-www-form-urlencoded", buff)
if err != nil {
log.Printf("An error occurred while sending a POST request to the server.\n Error: %v\n", err)
return nil
}
fmt.Println(resp.Header)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("An error occurred while reading the body of the response.\n Error: %v\n", err)
return nil
}
var decodeResponse interface{}
if err := json.Unmarshal(body, &decodeResponse); err != nil {
log.Printf("An error occurred while decoding the json response.Error: %v\n The response was %s\n", err, body)
return nil
}
jsonResponse := decodeResponse.(map[string]interface{})
var applicationId = jsonResponse["application-id"]
var key = jsonResponse["application-secret-key"]
log.Printf("The response from the server is %v\n Application-id: %v\n Key: %v\n", jsonResponse, applicationId, key)
params.Add("application-id", applicationId.(string))
hash := sha256.New()
hash.Write([]byte(params.Encode() + key.(string)))
md := hash.Sum(nil)
mdStr := hex.EncodeToString(md)
fmt.Printf("Hash: %s\n", hash)
params.Add("sig", mdStr)
return params
}
func newfileUploaRequest(uri string, params map[string][]string, paramName, path string) *http.Request {
file, err := os.Open(path)
if err != nil {
log.Printf("An error occured while opening the file %v.\n Error: %v\n", path, err)
os.Exit(1)
}
file2, err := os.Open(GetCurrentFile())
if err != nil {
log.Printf("An error occured while opening the file %v.\n Error: %v\n", path, err)
os.Exit(1)
}
defer file.Close()
defer file2.Close()
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile(paramName, filepath.Base(path))
if err != nil {
log.Printf("An error occured while creating a new form data-header.\n Error: %v\n", err)
os.Exit(1)
}
_, err = io.Copy(part, file)
part2, err := writer.CreateFormFile("script", filepath.Base(GetCurrentFile()))
if err != nil {
log.Printf("An error occured while creating a new form data-header.\n Error: %v\n", err)
os.Exit(1)
}
_, err = io.Copy(part2, file2)
for key, val := range params {
_ = writer.WriteField(key, val[0])
fmt.Printf("%v %v\n", key, val[0])
}
if err = writer.Close(); err != nil {
log.Printf("An error occured while closing the multipart writer \n Error: %v\n", err)
os.Exit(1)
}
request, err := http.NewRequest("POST", uri, body)
if err != nil {
log.Printf("An error occured while instantiating a POST request with the arbitraryfile.\n Error: %v\n", err)
}
request.Header.Set("Content-Type", writer.FormDataContentType())
return request
}
func GetCurrentFile() string {
_, filename, _, _ := runtime.Caller(1)
return filename
}
func main() {
path, _ := os.Getwd()
path += arbitraryfile
extraParams := generateSignature()
request := newfileUploaRequest(uri, extraParams, "arbitraryfile", path)
client := &http.Client{}
resp, err := client.Do(request)
if err != nil {
log.Printf("An error occured while making a HTTP POST request following policy as configured on the client.\n Error: %v\n", err)
} else {
log.Printf("arbitraryfile sent successfully, thank you for applying!\n")
body := &bytes.Buffer{}
_, err := body.ReadFrom(resp.Body)
if err != nil {
log.Printf("An error occured while reading the body of the response.\n Error: %v\n", err)
}
resp.Body.Close()
fmt.Println(resp.Status)
fmt.Println(resp.Header)
fmt.Println(body)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.